在具有矩阵子集的矩阵上应用函数

时间:2014-10-09 09:11:09

标签: r matrix

我有一个数字矩阵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}}

3 个答案:

答案 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