Как запустить tapply() на нескольких столбцах фрейма данных с помощью R?
У меня есть кадр данных, например:
a b1 b2 b3 b4 b5 b6 b7 b8 b9
D 4 6 9 5 3 9 7 9 8
F 7 3 8 1 3 1 4 4 3
R 2 5 5 1 4 2 3 1 6
D 9 2 1 4 3 3 8 2 5
D 5 4 3 1 6 4 1 8 3
R 3 7 9 1 8 5 3 4 2
D 4 1 8 2 6 3 2 7 5
F 7 1 7 2 7 1 6 2 4
D 6 3 9 3 9 9 7 1 2
Функция tapply(df[,2], INDEX = df$a, sum)
отлично работает, чтобы создать таблицу, которая суммирует все в df [, 2] by df $a, но когда я пытаюсь tapply(df[,2:10], INDEX = df$a, sum)
получить подобную таблицу, за исключением суммы для каждого столбца (2, 3, 4,..., 10), появляется сообщение об ошибке:
Ошибка при подключении (df [, 2:10], INDEX = df $a, sum): аргументы должны иметь одинаковую длину
Кроме того, мне бы хотелось, чтобы имена строк в таблице были именами столбцов df[,2:10]
, так что строка 1 является b1, строка 2 - b2, а строка 9 - b9.
Ответы
Ответ 1
Это потому, что tapply работает на векторах и преобразует df [, 2: 10] в вектор. Кроме того, сумма даст вам общую сумму, а не сумму за столбец. Используйте aggregate()
, например:
aggregate(df[,2:10],by=list(df$a), sum)
Если вы хотите вернуть список, вы можете использовать для него(). Не забудьте указать colSums вместо sum, как в результате работы с разделяемым фреймворком данных:
by(df[,2:10],df$a,FUN=colSums)
Ответ 2
Другая возможность заключается в объединении apply
и tapply
.
apply(df[,-1], 2, function(x) tapply(x, df$a, sum))
Производит вывод (который является матрицей)
b1 ... b9
D sD1 ... sD9
F sF1 ... sF9
R sR1 ... sR9
Затем вы можете использовать as.data.frame()
для получения кадра данных в качестве вывода.
Ответ 3
Вот способ применения data.table
к этой проблеме.
library(data.table)
DT <- data.table(df)
DT[, lapply(.SD, sum), by=a]
И вот подход dplyr
library(dplyr)
df %>% group_by(a) %>% summarise_each(funs(sum))