R Функція Apply () у певних стовпцях фреймів даних


75

Я хочу використовувати функцію apply у фреймі даних, але застосувати функцію лише до останніх 5 стовпців.

B<- by(wifi,(wifi$Room),FUN=function(y){apply(y, 2, A)})

Це стосується A для всіх стовпців y

B<- by(wifi,(wifi$Room),FUN=function(y){apply(y[4:9], 2, A)})

Це стосується A лише для стовпців 4-9 y, але загальна віддача B позбавляє перших 3 стовпців ... Я все ще хочу їх, я просто не хочу, щоб до них застосовували A.

wifi[,1:3]+B 

також робить не те, що я очікував / хотів.


2
Виклик "by" ускладнює це питання. Якщо це доречно, вам слід переписати питання для уточнення (що таке wifi $ Room?). У відповіді нижче я проігнорував.
leif

Ви могли б cbind(y[1:3], ...)до результату, який отримуєте.
IRTFM

Відповіді:


59

Використання прикладу data.frame та прикладної функції (лише +1 до всіх значень)

A <- function(x) x + 1
wifi <- data.frame(replicate(9,1:4))
wifi

#  X1 X2 X3 X4 X5 X6 X7 X8 X9
#1  1  1  1  1  1  1  1  1  1
#2  2  2  2  2  2  2  2  2  2
#3  3  3  3  3  3  3  3  3  3
#4  4  4  4  4  4  4  4  4  4

data.frame(wifi[1:3], apply(wifi[4:9],2, A) )
#or
cbind(wifi[1:3], apply(wifi[4:9],2, A) )

#  X1 X2 X3 X4 X5 X6 X7 X8 X9
#1  1  1  1  2  2  2  2  2  2
#2  2  2  2  3  3  3  3  3  3
#3  3  3  3  4  4  4  4  4  4
#4  4  4  4  5  5  5  5  5  5

Або навіть:

data.frame(wifi[1:3], lapply(wifi[4:9], A) )
#or
cbind(wifi[1:3], lapply(wifi[4:9], A) )

#  X1 X2 X3 X4 X5 X6 X7 X8 X9
#1  1  1  1  2  2  2  2  2  2
#2  2  2  2  3  3  3  3  3  3
#3  3  3  3  4  4  4  4  4  4
#4  4  4  4  5  5  5  5  5  5

Чи є спосіб зробити це за допомогою $індексації певного стовпця за іменем, а не [ : ]для індексування за номером стовпця? Я спробував додати імена col: colnames(wifi) = c("a", "b", "c", "d", "e", "f", "g", "h" ,"i")але жодної спроби використовувати lapply (wifi $ e, 2, X) не відбулося.
santeko

9
@skotturi - це можна зробити, як wifi[c("a","b","c")]для індексації кількох стовпців за назвою.
thelatemail

@ thelatemail, In apply(wifi[4:9],2, A), wifi[4:9]є. data.frameІ applyможе використовуватися лише для масиву або матриці. Чому ваша відповідь дієва?
kittygirl

@kittygirl - це тому, що apply можна використовувати на data.frame. Data.frame буде примушений до матриці як частина функції, коли застосовується apply.
thelatemail

@ thelatemail, втратить інформацію про ім'я рядка чи імені colname?
kittygirl

88

lapplyє, мабуть, кращим вибором, ніж applyтут, оскільки застосувати спочатку примушує ваш data.frame до масиву, що означає, що всі стовпці повинні мати однаковий тип. Залежно від вашого контексту, це може мати непередбачені наслідки.

Шаблон:

df[cols] <- lapply(df[cols], FUN)

Вектор "cols" може бути іменами змінних або індексами. Я вважаю за краще використовувати імена, коли це можливо (це надійно для переупорядкування стовпців). Отже, у вашому випадку це може бути:

wifi[4:9] <- lapply(wifi[4:9], A)

Приклад використання назв стовпців:

wifi <- data.frame(A=1:4, B=runif(4), C=5:8)
wifi[c("B", "C")] <- lapply(wifi[c("B", "C")], function(x) -1 * x)

2
Невелика корекція: wifi <- data.frame (A = 1: 4, B = runif (4), C = 5: 8)
jcfaria

Чи можете ви бути більш чіткими щодо того, як ви створили вектор [cols]?
Мокс

@Mox ти можеш просто зробитиcols <- c("var1", "var2")
cparmstrong

як альтернативу, використовуючи dplyr, уникаючи надмірності для повторення специфікації стовпця, ви могли б це зробитиwifi[4:9] %<>% map_dbl(A)
Agile Bean

1

Як вже згадувалося, вам просто потрібна стандартна applyфункція R, застосована до стовпців ( MARGIN=2):

wifi[,4:9] <- apply(wifi[,4:9], MARGIN=2, FUN=A)

Або, коротко:

wifi[,4:9] <- apply(wifi[,4:9], 2, A)

Це оновлює стовпці 4: 9 на місці за допомогою A()функції. Тепер припустимо, що na.rmце аргумент A(), яким він, мабуть, і повинен бути. Ми можемо передати na.rm=Tвидалення значень NA з обчислення так:

wifi[,4:9] <- apply(wifi[,4:9], MARGIN=2, FUN=A, na.rm=T)

Те саме стосується будь-яких інших аргументів, які ви хочете передати своїй користувацькій функції.


0

Я думаю, що ти хочеш, це mapply. Ви можете застосувати функцію до всіх стовпців, а потім просто опустити потрібні вам стовпці. Однак, якщо ви застосовуєте різні функції до різних стовпців, здається, ймовірно, що ви хочете змінити , з пакета dplyr.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.