在R中按行分组求和

7

这是一个有点难以命名的问题,欢迎编辑。数据看起来像这样:

mat =         

     [,1]
 [1,] 9.586352e-04
 [2,]           NA
 [3,] 2.605841e-03
 [4,] 7.868957e-05
 [5,] 1.000000e+00
 [6,]           NA
 [7,] 8.208500e-02
 [8,] 2.605841e-03
 [9,] 7.868957e-05
[10,] 1.000000e+00
[11,] 9.586352e-04
[12,] 8.208500e-02
[13,] 2.605841e-03
[14,] 7.868957e-05
[15,] 1.000000e+00

我想将每5个元素相加,由于有15个元素,返回的向量长度应为3(15/3)。例如,将缺失值视为0进行计算。

我该如何做到这一点?

我还想忽略缺失值。


请问您能否发布填充mat值的代码?mat是一个矩阵吗? - nio
“vapply(split(EXPnumerator, rep(1:3, each = 5)), sum, 1L)中出现错误: 数值必须为'integer'类型, 但是FUN(X[[1]])的结果为'double'类型。 此外:警告信息: 在split.default(EXPnumerator, rep(1:3, each = 5))中: 数据长度不是分裂变量的倍数。” - wolfsatthedoor
1 2 3 0.007817522 0.000000000 0.000000000 警告信息: 在split.default(mat,rep(1:3,each = 5))中: 数据长度不是分割变量的倍数。 - wolfsatthedoor
抱歉,我的错,它起作用了,但前两个返回NA。 - wolfsatthedoor
1 2 3 NA NA 1.085728 - wolfsatthedoor
5个回答

6
m <- matrix(1:15, ncol = 1)
m[cbind(c(3,7),c(1, 1))] <- NA

library(zoo)
rollapply(m, sum, width = 5, by = 5, na.rm = TRUE)
     [,1]
[1,]   12
[2,]   33
[3,]   65

6
您可以使用 tapply()
mat <- matrix(c(1, 2, NA, 4:6, NA, 8:15))
## set up a grouping vector
grp <- rep(1:(nrow(mat)/5), each = 5)
## compute group sums
tapply(mat, grp, sum, na.rm = TRUE)
#  1  2  3 
# 12 33 65   

一种效率较低的选项是使用split()vapply()

vapply(split(mat, grp), sum, 1, na.rm = TRUE)
#  1  2  3 
# 12 33 65 

使用rep(1:(nrow(mat)/5), each=5)比使用rep(1:3, each = 5)更好吗? - Scott C Wilson
是的,这样会更加泛化一些。 - Rich Scriven

5

这非常适合?rowsum,应该很快

使用RStudent的数据

rowsum(m, rep(1:3, each=5), na.rm=TRUE)

第二个参数group定义了要对其进行求和的行。更一般地,可以将组参数定义为rep(1:nrow(m), each=5, length=nrow(m))(如果在向量上应用,请使用length替换nrow)。

2
使用dplyr
library(dplyr)
mat <- matrix(c(1, 2, NA, 4:6, NA, 8:15))
df <- data.frame(mat)

df %>%
  mutate(group = rep(1:(n()/5), each=5)) %>%
  group_by(group) %>%
  summarise(mat = sum(mat, na.rm = TRUE))

你会得到:
#Source: local data frame [3 x 2]

#  group mat
#1     1  12
#2     2  33
#3     3  65

如果出于某些原因,您想将 NA 替换为 0(因为您想执行一些不同于 sum() 的其他操作,比如 mean()),您可以这样做:

df %>%
  mutate(mat = ifelse(is.na(mat), 0, mat)) %>%
  mutate(group = rep(1:(n()/5), each=5)) %>%
  group_by(group) %>%
  summarise(mat = mean(mat))

你将得到结果,其中NA等于0(而不是在先前的建议中使用na.rm = TRUE省略NA

#Source: local data frame [3 x 2]

#  group  mat
#1     1  2.4
#2     2  6.6
#3     3 13.0

0

sum函数有一个na.rm选项。

dfsum <- numeric()
i <- 1
j <- 1
while (i < nrow(df)) { 
    dfsum[j] <- sum(df[i,2] : df [i+4,2], na.rm=TRUE)
    i <- i+5
    j <- j+ 1
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接