R 用两个变量汇总多个列

R 用两个变量汇总多个列,r,R,这是我第一次使用R,所以如果这个问题措辞不当,请原谅我。我有一个导入R的.csv文件,我正试图总结一些数据。给定年份、研究地点和区域的每行数据,以及每列的物种数量。每个物种有4列,因为有4次调查可以看到该物种 我试图得到每年和研究地点的每个物种的总数。第5:8列是一个物种,第9:12列是另一个物种,第13:16列是另一个物种,依此类推。以下是我认为可以按年份(YYYY)和研究区域(SAR)总结第5:8列的代码: 这给了我一个错误消息“参数必须具有相同的长度”。有人能帮我完成这第一步吗 以下是一些

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

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

这给了我一个错误消息“参数必须具有相同的长度”。有人能帮我完成这第一步吗

以下是一些数据:

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'找到)”


我回去检查了数据,所有的变量长度都是相同的。

我们可以使用
聚合
数据。表
dplyr
。如果我们对
aggregate
使用公式方法,当不同列中存在
na
值时,我们需要设置
na.action=NULL
。默认情况下,
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”分组,并使用
summary\u 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.frame”转换为“data.table”(
setDT(test)
),按“SAR”、“YYYY”分组,循环遍历data.table的子集(
.SD
)并得到
和。要循环的列在
.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)

DT请展示一些示例数据和预期输出。以下是我拥有的一些数据:请在您的帖子中更新它。顺便说一句,您能否指定
yyy
SAR
s在数据集中的位置对不起,我很难确定如何将我的数据表的一部分添加到注释中。SAR和YYYY分别是第1列和第2列的标题。此外,我如何告诉R汇总第5:8、9:12、13:16列等,直到我的数据结束?@HVS如我所示,您可以在
select
中使用
dplyr
数据表中的
.SDcols
指定列位置。i、 e.
.SDcols=5:ncol(test)
。当我复制并粘贴您在上面发布的数据到R中时,它会运行,但使用聚合函数没有收到错误消息,错误消息一定是由于在excel中创建列,然后将其转换为.csv文件的方式造成的。关于.SDcols=5:ncol(test)命令,我仍然有点不清楚。我不明白该语句是如何告诉R读取我上面提到的列的。@HVS实际上,您引用了
“col1”
等,从而得到了
aggregate
的错误。我们在
.SDcols
中指定列的位置或名称,并基于此,循环遍历这些列(
lappy(.SD,
)我总共有328列。
 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)