2014-02-18 5 views
8

У меня есть большая таблица данных (из пакета data.table) с более чем 60 столбцами (первые три соответствуют факторам и остальным для переменных ответа, в данном случае разных видов) и несколько рядов, соответствующих различным уровням обработки и обилиям видов. Очень маленькая версия выглядит следующим образом:Суммирование по строкам таблицы данных. Для конкретных столбцов

library(data.table) 
TEST <- data.table(Time=c("0","0","0","7","7","7","12"), 
      Zone=c("1","1","0","1","0","0","1"), 
      quadrat=c(1,2,3,1,2,3,1), 
      Sp1=c(0,4,29,9,1,2,10), 
      Sp2=c(20,17,11,15,32,15,10), 
      Sp3=c(1,0,1,1,1,1,0)) 

setkey(TEST,Time) 
TEST 

# Time Zone quadrat Sp1 Sp2 Sp3 
# 1: 0 1  1 0 20 1 
# 2: 0 1  2 4 17 0 
# 3: 0 0  3 29 11 1 
# 4: 12 1  1 10 10 0 
# 5: 7 1  1 9 15 1 
# 6: 7 0  2 1 32 1 
# 7: 7 0  3 2 15 1 

я сначала хочу, чтобы вычислить средние содержаний каждого вида по времени для каждой зоны х комбинации QUADRAT и это нормально:

Abundance = TEST[ , lapply(.SD, mean), by = "Zone,quadrat"] 
Abundance 
# Zone quadrat Time  Sp1 Sp2  Sp3 
# 1: Z1  1 NA 6.333333 15.0 0.6666667 
# 2: Z1  2 NA 2.500000 24.5 0.5000000 
# 3: Z0  1 NA 15.500000 13.0 1.0000000 

Тогда я хочу вычислить сумму ролей для столбцов вида, в примере от Sp1 до Sp3. Я попытался следующий код без успеха:

Abundance$SumAbundance <- rowSums(Abundance[ , c(4:6)]) 

Я получаю сообщение об ошибке:

# Error in rowSums(Abundance[, c(4:6)]) : 
# 'x' must be an array of at least two dimensions 

Как я могу вычислить строки суммы для отдельных столбцов data.table?

ответ

13

Фактически тип Abundance[, c(4:6)], чтобы узнать, что результат, и вам будет ясно, почему это не сработало. Это может быть исправлено с помощью with = FALSE, но лучше синтаксис (с меньшим количеством копирования) является:

Abundance[, SumAbundance := rowSums(.SD), .SDcols = 4:6] 

Кроме того, я не проверял, но у меня есть подозрение, что это будет быстрее, так как он не будет конвертировать в matrix, как rowSums делает:

Abundance[, SumAbundance := Reduce(`+`, .SD), .SDcol = 4:6] 
+0

Привет, @eddi, это здорово, что это работает. Не могли бы вы объяснить, почему оригинальная версия (Abundance [, c (4: 6)]) сделала это? –

+1

@ClaireG см. Пункт '1.1' в [FAQ] (http://datatable.r-forge.r-project.org/datatable-faq.pdf) – eddi

+0

@eddi, как работать, если некоторые из значений NA, и вы хотите избавиться от них в сокращенной версии –

3

альтернативным (data.table) подход будет хранить ваши данные в длинной форме. Версия 1.8.11 от data.table имеет быстрый melt и dcast методы

library(reshape2) 
mt <- melt(test, id=1:3,variable.name='Species') 

abundance <- mt[,list(abundance = mean(value)),by=list(Zone,quadrat,Species)][, 
       sumAbundance := sum(abundance), by = list(Zone,quadrat)] 

Работа в длинном формате будет принимать небольшие изменения в мышлении, но он может оказаться более эффективной памяти мудрым (как будет задействовано меньше внутреннее копирование, и вы ссылаетесь на один не несколько элементов в каждой группе «by».)

+0

Я боюсь, что это не сработает, и я не уверен, что это лучший способ, поскольку у меня есть 63 вида (переменных) в моем фактическом наборе данных ... –

+0

ОК, после попытки обновить до версии 1.8.11 data.table (извините ...) команды работают, но это не то, что я хочу сделать: я хочу суммировать средства вида, поэтому команды, предложенные выше, @eddi - путь для меня. –

+0

@ClaireG - Я изменил свой пример. Работа в «длинной» форме будет немного привыкать. – mnel

Смежные вопросы