对 matrix/data 帧中的行组进行操作
operation on groups of rows in a matrix/data frame
假设我有一个矩阵(可以是一个可强制转换为矩阵的数据框,反之亦然)
X=matrix(rnorm(45), nr=15 )
[,1] [,2] [,3]
[1,] -0.35659671 -0.5014418 -0.90051481
[2,] -2.84945987 -0.6558198 -1.59163998
[3,] -0.03612257 0.7118217 -0.76520379
[4,] 2.45922337 -1.4965018 -0.28132609
[5,] -0.46939481 -2.2576689 -0.91045703
[6,] 0.65121124 -0.4879071 -1.81893484
[7,] -0.28633954 0.3570085 -2.40230043
[8,] -1.32283279 -0.4904968 0.42214466
[9,] 0.55199355 -1.5181311 -0.62465292
[10,] -1.00114458 0.5140162 -0.01261708
[11,] -1.49307374 0.1734213 1.38231439
[12,] -1.71157588 -0.7030724 -1.05475532
[13,] 1.13823870 1.3380262 2.74988880
[14,] -0.41600520 -0.9527629 0.68447386
[15,] -1.25893418 -0.3633260 0.38870010
获取列总和很容易(colSums,或apply,或任何首选方法)。但是,我有一个位置索引,比方说
idx=c(3,7,13)
所以我需要拆分矩阵并对小节中的列求和(或者,通常,执行某些功能),例如第 1 到 3、4 到 7、8 到 13 和 14 到 15 行(最后一行)并得到 4×3 矩阵
[,1] [,2] [,3]
[1,] -3.2421792 -0.4454399 -3.2573586
[2,] 2.3547000 -3.8850690 -5.4130180
[3,] -3.8383947 -0.6862365 2.8623225
[4,] -1.6749390 -1.3160890 1.0731740
这是一个最小的可重现示例。真正的矩阵要大得多,分段的个数和位置都是可变的,函数也更复杂:)
尝试
indx <- c(idx[1],diff(c(idx, nrow(X))))
rownames(X) <- rep(seq_along(indx), indx)
res <- rowsum(X, group=rownames(X))
dimnames(res) <- NULL
res
# [,1] [,2] [,3]
#[1,] -3.242179 -0.4454399 -3.257359
#[2,] 2.354700 -3.8850693 -5.413018
#[3,] -3.838395 -0.6862366 2.862323
#[4,] -1.674939 -1.3160889 1.073174
或者如果我们在更改 row.names 后将 'matrix' 转换为 'data.table`,
library(data.table)#v1.9.5+
as.data.table(X, keep.rownames=TRUE)[, lapply(.SD, sum), by=rn]
# rn V1 V2 V3
#1: 1 -3.242179 -0.4454399 -3.257359
#2: 2 2.354700 -3.8850693 -5.413018
#3: 3 -3.838395 -0.6862366 2.862323
#4: 4 -1.674939 -1.3160889 1.073174
或者在 'X'
中更改行名之前使用 dplyr
library(dplyr)
as.data.frame(X) %>%
group_by(rn=rep(seq_along(indx), indx)) %>%
summarise_each(funs(sum))
#rn V1 V2 V3
#1 1 -3.242179 -0.4454399 -3.257359
#2 2 2.354700 -3.8850693 -5.413018
#3 3 -3.838395 -0.6862366 2.862323
#4 4 -1.674939 -1.3160889 1.073174
您也可以使用 Map
,然后使用 do.call
和 rbind
来获得想要的矩阵:
do.call(rbind, Map(function(u,v) colSums(X[u:v,]), c(1, idx+1), c(idx, nrow(X))))
假设我有一个矩阵(可以是一个可强制转换为矩阵的数据框,反之亦然)
X=matrix(rnorm(45), nr=15 )
[,1] [,2] [,3]
[1,] -0.35659671 -0.5014418 -0.90051481
[2,] -2.84945987 -0.6558198 -1.59163998
[3,] -0.03612257 0.7118217 -0.76520379
[4,] 2.45922337 -1.4965018 -0.28132609
[5,] -0.46939481 -2.2576689 -0.91045703
[6,] 0.65121124 -0.4879071 -1.81893484
[7,] -0.28633954 0.3570085 -2.40230043
[8,] -1.32283279 -0.4904968 0.42214466
[9,] 0.55199355 -1.5181311 -0.62465292
[10,] -1.00114458 0.5140162 -0.01261708
[11,] -1.49307374 0.1734213 1.38231439
[12,] -1.71157588 -0.7030724 -1.05475532
[13,] 1.13823870 1.3380262 2.74988880
[14,] -0.41600520 -0.9527629 0.68447386
[15,] -1.25893418 -0.3633260 0.38870010
获取列总和很容易(colSums,或apply,或任何首选方法)。但是,我有一个位置索引,比方说
idx=c(3,7,13)
所以我需要拆分矩阵并对小节中的列求和(或者,通常,执行某些功能),例如第 1 到 3、4 到 7、8 到 13 和 14 到 15 行(最后一行)并得到 4×3 矩阵
[,1] [,2] [,3]
[1,] -3.2421792 -0.4454399 -3.2573586
[2,] 2.3547000 -3.8850690 -5.4130180
[3,] -3.8383947 -0.6862365 2.8623225
[4,] -1.6749390 -1.3160890 1.0731740
这是一个最小的可重现示例。真正的矩阵要大得多,分段的个数和位置都是可变的,函数也更复杂:)
尝试
indx <- c(idx[1],diff(c(idx, nrow(X))))
rownames(X) <- rep(seq_along(indx), indx)
res <- rowsum(X, group=rownames(X))
dimnames(res) <- NULL
res
# [,1] [,2] [,3]
#[1,] -3.242179 -0.4454399 -3.257359
#[2,] 2.354700 -3.8850693 -5.413018
#[3,] -3.838395 -0.6862366 2.862323
#[4,] -1.674939 -1.3160889 1.073174
或者如果我们在更改 row.names 后将 'matrix' 转换为 'data.table`,
library(data.table)#v1.9.5+
as.data.table(X, keep.rownames=TRUE)[, lapply(.SD, sum), by=rn]
# rn V1 V2 V3
#1: 1 -3.242179 -0.4454399 -3.257359
#2: 2 2.354700 -3.8850693 -5.413018
#3: 3 -3.838395 -0.6862366 2.862323
#4: 4 -1.674939 -1.3160889 1.073174
或者在 'X'
中更改行名之前使用dplyr
library(dplyr)
as.data.frame(X) %>%
group_by(rn=rep(seq_along(indx), indx)) %>%
summarise_each(funs(sum))
#rn V1 V2 V3
#1 1 -3.242179 -0.4454399 -3.257359
#2 2 2.354700 -3.8850693 -5.413018
#3 3 -3.838395 -0.6862366 2.862323
#4 4 -1.674939 -1.3160889 1.073174
您也可以使用 Map
,然后使用 do.call
和 rbind
来获得想要的矩阵:
do.call(rbind, Map(function(u,v) colSums(X[u:v,]), c(1, idx+1), c(idx, nrow(X))))