我有一个数字矩阵mat
和一个大小相同的逻辑矩阵ind
。我的目标非常基本:在条目上按行fun
应用ind
,由set.seed(42)
mat <- matrix(1:20, 4)
ind <- matrix(sample(c(F, T), 20, replace = T), 4)
fun <- function(x) sum(x)
表示。这是一个例子:
fun
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 9 13 17
[2,] 2 6 10 . .
[3,] . 7 . . .
[4,] 4 . 12 16 20
的“有效”子集是:
sapply(1:ncol(mat), function(i) fun(mat[ind[, i], i]))
[1] 7 18 31 29 37
我目前的解决方案:
mat * ind
它完成了这项工作,但我有一种感觉,我错过了一些非常简单和优雅的东西。有什么想法吗?
编辑:这是另一个不能容忍额外零的函数,所以乘以fun2 <- function(x) sd(x)
sapply(1:ncol(mat), function(i) fun2(mat[ind[, i], i]))
[1] 1.527525 1.000000 1.527525 2.121320 2.121320
将无法正常工作。
{{1}}
答案 0 :(得分:2)
在这种情况下,使用apply over columns,与逻辑矩阵相乘应该起作用:
> apply(mat*ind,2,fun)
[1] 7 18 31 29 37
为了在更一般的情况下更好地处理FALSE(在乘法中评估为0),您可以将其更改为NA并具有知道如何处理NA的函数,例如:
ind<- ifelse(ind == FALSE, NA, ind)
fun <- function(x) sum(x, na.rm=TRUE)
apply(mat*ind,2,fun)
这可以推广到你想要应用的任何函数,并明确处理NA。
答案 1 :(得分:1)
试试这个:
colSums(mat * ind)
#[1] 7 18 31 29 37
答案 2 :(得分:1)
tapply
的一种非常简单的方法:
tapply(mat[ind], col(mat)[ind], fun)
# 1 2 3 4 5
# 7 18 31 29 37
使用mapply
的另一种方法:
mapply(function(m, i) fun(m[i]), split(mat, col(mat)), split(ind, col(mat)))
# 1 2 3 4 5
# 7 18 31 29 37