用两个变量汇总多列

时间:2015-11-13 17:50:10

标签: r

这是我第一次使用R所以如果这个问题措辞不当,请原谅我。我有一个.csv文件,我导入到R,我试图总结一些数据。如果对于给定年份,研究地点和区域以及每列具有存在的物种数量,则每行数据。每个物种有4列,因为有4个调查可以看到物种。

我试图按年份和研究地点获得每个物种的总和。第5:8列是一种,9:12是另一种,13:16是另一种,依此类推。以下是我认为按年(YYYY)和研究区域(SAR)汇总第5:8列的代码:

aggregate(test[,5:8],by = list("SAR","YYYY"), FUN = sum, na.rm = TRUE)

这给了我一个错误信息,即"参数必须具有相同的长度"。任何人都可以帮助我完成这一步骤吗?

以下是一些数据:

SAR    YYYY GRID_ID WID     col1 col2 col3 col4
BCPALP  2005    1   1189    NA  NA  0   0
BCPALP  2005    1   1190    0   NA  0   0
BCPALP  2005    1   1191    0   0   NA  NA
BCPALP  2005    1   1192    0   NA  NA  NA
BCPALP  2005    1   1194    NA  NA  1   NA
BCPALP  2005    1   1195    NA  NA  1   NA
BCPALP  2005    1   1196    0   NA  0   NA
BCPALP  2005    1   1198    0   NA  0   NA
BCPALP  2005    1   1199    0   NA  0   0

我希望获得类似这样的输出:

SAR    YYYY    total of columns 1:4
BCPALP 2005    2

这是我刚试过的代码。

aggregate(cbind("col1", "col2", "col3", "col4")~SAR+YYYY, test, FUN=sum, na.rm=TRUE, na.action=NULL)

它给出了一条错误消息,指出"变量长度不同(找到' SAR')"。

我回去检查了数据,所有变量都是一样的。

1 个答案:

答案 0 :(得分:1)

我们可以使用aggregatedata.tabledplyr。如果我们使用aggregate的公式方法,我们需要在不同列中有na.action=NULL值时设置NA。默认情况下为na.action=na.omit,因此如果其中一列中只有一个NA,则该行将从计算中删除。

aggregate(cbind(col1, col2, col3, col4)~SAR+YYYY, test,
                        FUN=sum, na.rm=TRUE, na.action=NULL)
#   SAR YYYY col1 col2 col3 col4
#1 BCPALP 2005    0    0    2    0

使用dplyr,我们按'SAR','YYYY'分组,并使用summarise_each获取每个'col'的sum

library(dplyr)
test %>%
     group_by(SAR, YYYY) %>%
     summarise_each(funs(sum=sum(., na.rm=TRUE)), 5:ncol(test))
#     SAR  YYYY  col1  col2  col3  col4
#   (chr) (int) (int) (int) (int) (int)
#1 BCPALP  2005     0     0     2     0

data.table。我们将'data.frame'转换为'data.table'(setDT(test)),按'SAR','YYYY'分组,我们循环通过Data.table的子集(.SD)并得到sum。要循环的列在.SDcols

中指定
library(data.table)
setDT(test)[, lapply(.SD, sum, na.rm=TRUE), by = .(SAR, YYYY),
             .SDcols= 5:ncol(test)]  
#      SAR YYYY col1 col2 col3 col4
#1: BCPALP 2005    0    0    2    0

更新

假设在聚合之后我们需要得到列'col1:col4',然后'col5:col8'等的行方式总和。

 DT <- setDT(test1)[, lapply(.SD, sum, na.rm=TRUE),
              by = .(SAR, YYYY), .SDcols= 5:ncol(test1)]
 DT1 <- melt(DT, id.var=c('SAR', 'YYYY'))[, i1 := as.numeric(gl(.N, 4, .N)),
            .(SAR, YYYY)]
 dcast(DT1, SAR+YYYY~i1, value.var='value', sum)

数据

 test <- structure(list(SAR = c("BCPALP", "BCPALP",
"BCPALP", "BCPALP", 
"BCPALP", "BCPALP", "BCPALP", "BCPALP", "BCPALP"), YYYY = c(2005L, 
2005L, 2005L, 2005L, 2005L, 2005L, 2005L, 2005L, 2005L),
GRID_ID = c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), WID = c(1189L, 1190L, 1191L, 
1192L, 1194L, 1195L, 1196L, 1198L, 1199L), col1 = c(NA, 0L, 0L, 
0L, NA, NA, 0L, 0L, 0L), col2 = c(NA, NA, 0L, NA, NA, NA, NA, 
NA, NA), col3 = c(0L, 0L, NA, NA, 1L, 1L, 0L, 0L, 0L), col4 = c(0L, 
0L, NA, NA, NA, NA, NA, NA, 0L)), .Names = c("SAR", "YYYY",
"GRID_ID", 
"WID", "col1", "col2", "col3", "col4"), class = "data.frame", 
 row.names = c(NA, -9L))

set.seed(24)
m1 <- matrix(sample(c(NA,0:5), 9*4, replace=TRUE),ncol=4, 
           dimnames=list(NULL, paste0('col', 5:8)))
test1 <- cbind(test, m1)