矩阵中每k列R求和

矩阵中每k列R求和,r,matrix,R,Matrix,我有一个矩阵temp1(维数Nx16)(通常为NxM) 我想将每行中的每k列求和为一个值 以下是我到目前为止的收获: cbind(rowSums(temp1[,c(1:4)]), rowSums(temp1[,c(5:8)]), rowSums(temp1[,c(9:12)]), rowSums(temp1[,c(13:16)])) 必须有一种更优雅(更普遍)的方法来做这件事 我注意到类似的问题: 无法使它与阿南达的解决方案一起工作; 出现以下错误: sapply(split.default

我有一个矩阵temp1(维数Nx16)(通常为NxM)

我想将每行中的每k列求和为一个值

以下是我到目前为止的收获:

cbind(rowSums(temp1[,c(1:4)]), rowSums(temp1[,c(5:8)]), rowSums(temp1[,c(9:12)]), rowSums(temp1[,c(13:16)]))
必须有一种更优雅(更普遍)的方法来做这件事

我注意到类似的问题:

无法使它与阿南达的解决方案一起工作; 出现以下错误:

sapply(split.default(temp1,0:(长度(temp1)-1)%/%4),行和)

乐趣中的错误(X[[1L]],…):
“x”必须是至少具有两个维度的数组


请告知。

如果子矩阵的维度相等,您可以将维度更改为
数组
,然后执行
行和

 m1 <- as.matrix(temp1)
 n <- 4
 dim(m1) <- c(nrow(m1), ncol(m1)/n, n)
 res <- matrix(rowSums(apply(m1, 2, I)), ncol=n)
 identical(res[,1],rowSums(temp1[,1:4]))
 #[1] TRUE
m1另一种可能性:

x1<-sapply(1:(ncol(temp1)/4),function(x){rowSums(temp1[,1:4+(x-1)*4])})

## check
x0<-cbind(rowSums(temp1[,c(1:4)]), rowSums(temp1[,c(5:8)]), rowSums(temp1[,c(9:12)]), rowSums(temp1[,c(13:16)]))
identical(x1,x0)
# TRUE

x1这里是另一种方法。将矩阵转换为数组,然后将
apply
sum
一起使用

n <- 4
apply(array(temp1, dim=c(dim(temp1)/c(1,n), n)), MARGIN=c(1,3), FUN=sum)

n将矩阵列与每组大小
n
列求和的函数

set.seed(1618)
mat <- matrix(rnorm(24 * 16), 24, 16)

f <- function(mat, n = 4) {
  if (ncol(mat) %% n != 0)
    stop()
  cols <- split(colSums(mat), rep(1:(ncol(mat) / n), each = n))
  ## or use this to have n mean the number of groups you want
  # cols <- split(colSums(mat), rep(1:n, each = ncol(mat) / n))
  sapply(cols, sum)
}

f(mat, 4)
#          1          2          3          4 
# -17.287137  -1.732936  -5.762159  -4.371258 

c(sum(mat[,1:4]), sum(mat[,5:8]), sum(mat[,9:12]), sum(mat[,13:16]))
# [1] -17.287137  -1.732936  -5.762159  -4.371258

您可以通过以下方式使用

do.call(cbind, by(t(temp1), (seq(ncol(temp1)) - 1) %/% 4, FUN = colSums))

你能解释一下这个代码吗?:m1@robertevansanders首先,我们将“temp1”转换为
矩阵
,然后通过改变尺寸(
dim(m1))将其更改为数组(3d)
set.seed(24)
temp1 <- matrix(sample(1:20, 16*4, replace=TRUE), ncol=16)
set.seed(1618)
mat <- matrix(rnorm(24 * 16), 24, 16)

f <- function(mat, n = 4) {
  if (ncol(mat) %% n != 0)
    stop()
  cols <- split(colSums(mat), rep(1:(ncol(mat) / n), each = n))
  ## or use this to have n mean the number of groups you want
  # cols <- split(colSums(mat), rep(1:n, each = ncol(mat) / n))
  sapply(cols, sum)
}

f(mat, 4)
#          1          2          3          4 
# -17.287137  -1.732936  -5.762159  -4.371258 

c(sum(mat[,1:4]), sum(mat[,5:8]), sum(mat[,9:12]), sum(mat[,13:16]))
# [1] -17.287137  -1.732936  -5.762159  -4.371258
## first 8 and last 8 cols
f(mat, 8)
#         1         2 
# -19.02007 -10.13342 

## each group is 16 cols, ie, the entire matrix
f(mat, 16)
#         1 
# -29.15349 

sum(mat)
# [1] -29.15349
do.call(cbind, by(t(temp1), (seq(ncol(temp1)) - 1) %/% 4, FUN = colSums))