【问题标题】:Apply a function over a matrix with matrix subsetting在具有矩阵子集的矩阵上应用函数
【发布时间】:2014-12-04 03:42:47
【问题描述】:

我有一个相同大小的数字矩阵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

【问题讨论】:

    标签: r matrix


    【解决方案1】:

    在这种情况下,对列使用应用,同时与逻辑矩阵相乘应该可以:

    > 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。

    【讨论】:

    • 好主意。虽然在那种情况下fun 被输入了像 (1, 2, 0, 4) 这样的向量而不是 (1, 2, 4),这对 sum 没有影响,但对于任何 fun 都没有。
    • 是的,不过也有这个问题,并添加了一个可能的解决方案。在进一步处理中转换 FALSE -> NA 可能会更好。
    【解决方案2】:

    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 
    

    【讨论】:

    • 我只花了半个小时就弄清楚了它是如何工作的。严肃的魔法。
    【解决方案3】:

    试试这个:

    colSums(mat * ind)
    #[1]  7 18 31 29 37
    

    【讨论】:

    • 是的,我发帖后就想到了。我猜@fileunderwater 在这种情况下的解决方案会对您的任务更有帮助?
    • 不幸的是,仅适用于将“零”视为“无”的函数。
    • 什么是 NA 的?如果你做类似mat[!ind] &lt;- NA 的事情?
    • fun2 &lt;- function(x) sd(x, na.rm=T); mat[!ind] &lt;- NAapply(mat, 2, fun2) 产生与您编辑的问题相同的输出.. 不确定您的实际问题是否可以接受。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多