Ответ 1
вам следует использовать .SDcols
(особенно если у вас слишком много столбцов и требуется, чтобы определенная операция выполнялась только над подмножеством столбцов (кроме группируемых переменных столбцов).
dtb[, lapply(.SD, mean), by=condition, .SDcols=2:4]
# condition var1 var2 var3
# 1: one 101.0 1001.0 10001.0
# 2: two 104.0 1004.0 10004.0
# 3: three 107.0 1007.0 10007.0
# 4: four 109.5 1009.5 10009.5
Вы также можете получить все имена столбцов, которые вы хотите получить в начале, в переменной, а затем передать их в .SDcols
следующим образом:
keys <- setdiff(names(dtb), "condition")
# keys = var1, var2, var3
dtb[, lapply(.SD, mean), by=condition, .SDcols=keys]
Редактировать: Как правильно заметил Мэтью Доул, поскольку вам требуется вычислять среднее значение для каждого другого столбца после группировки по condition
, вы можете просто сделать:
dtb[, lapply(.SD, mean), by=condition]
Дэвид редактировать: (который был отклонен): узнайте больше о .SD
из этого поста. Я считаю, что это актуально здесь. Спасибо, Дэвид.
Изменить 2: Предположим, у вас есть data.table
с 1000 строками и 301 столбцом (один столбец для группировки и 300 числовых столбцов):
require(data.table)
set.seed(45)
dt <- data.table(grp = sample(letters[1:15], 1000, replace=T))
m <- matrix(rnorm(300*1000), ncol=300)
dt <- cbind(dt, m)
setkey(dt, "grp")
и вы хотели найти среднее значение столбцов, скажем, 251: 300,
Вы можете вычислить среднее значение для всех столбцов, а затем подгруппировать эти столбцы (что не очень эффективно, поскольку вы будете вычислять все данные).
dt.out <- dt[, lapply(.SD, mean), by=grp] dim(dt.out) # 15 * 301, not efficient.
вы можете сначала отфильтровать
data.table
только по этим столбцам, а затем вычислить среднее значение (что опять-таки не обязательно является лучшим решением, поскольку вам нужно создавать дополнительный поднабор данных.таблицы каждый раз, когда вы хотите выполнить операции с определенными столбцами.dt.sub <- dt[, c(1, 251:300)] setkey(dt.sub, "grp") dt.out <- dt.sub[, lapply(.SD, mean), by=grp]
вы можете указывать каждый из столбцов один за другим, как вы это обычно делаете (но это желательно для небольших таблиц data.tables)
# if you just need one or few columns dt.out <- dt[, list(m.v251 = mean(V251)), by = grp]
Так какое лучшее решение? Ответ .SDcols.
Как указано в документации, для data.table x .SDcols указывает столбцы, включенные в .SD.
Это в основном неявно фильтрует столбцы, которые будут переданы в .SD вместо создания подмножества (как мы делали раньше), только это ОЧЕНЬ эффективно и БЫСТРО!
Как мы можем это сделать?
Указав номера столбцов:
dt.out <- dt[, lapply(.SD, mean), by=grp, .SDcols = 251:300] dim(dt.out) # 15 * 51 (what we expect)
Или в качестве альтернативы, указав идентификатор столбца:
ids <- paste0("V", 251:300) # get column ids dt.out <- dt[, lapply(.SD, mean), by=grp, .SDcols = ids] dim(dt.out) # 15 * 51 (what we expect)
Он принимает имена столбцов и номера в качестве аргументов. В обоих случаях .SD будет предоставляться только с теми столбцами, которые мы указали.
Надеюсь это поможет.