【问题标题】:How to write an apply() function that only applies to odd-numbered columns in r matrix?如何编写仅适用于 r 矩阵中奇数列的 apply() 函数?
【发布时间】:2021-12-25 20:25:27
【问题描述】:

假设我们有一个如下所示的“测试”矩阵:(1,2,3, 4,5,6, 7,8,9, 10,11,12) 通过运行test <- matrix(1:12, ncol = 4) 生成。一个简单的 3 x 4(行 x 列)矩阵,包含从 1 到 12 的数字。

现在假设我们想为每个 奇数 矩阵列中的每个元素添加一个值 1,所以我们最终得到一个包含以下值的矩阵:(2,3, 4、4、5、6、8、9、10、10、11、12)。我们如何使用apply() 函数来做到这一点?

请注意,这是一个简化的示例。在我正在使用的更完整的代码中,矩阵根据用户输入动态扩展/收缩,因此我需要一个 apply() 函数来计算矩阵列的实际数量,而不是使用上述 4 列的固定假设例子。 (而且我没有向元素添加值 1;我正在运行并行最小值函数 test[,1] <- pmin(test1[,1], 5) 以将每个值限制为最大值 5)。

由于我目前对apply() 系列函数的了解有限,目前我所能做的就是apply(test, 2, function(x) {return(x+1)}),但这是为所有列中的所有元素添加值1,而不仅仅是奇数列。

【问题讨论】:

    标签: r matrix apply


    【解决方案1】:

    您可以简单地对输入数据框进行子集化以仅访问奇数或偶数列。考虑:

    test[c(TRUE, FALSE)] <- apply(test[c(TRUE, FALSE)], 2, function(x) f(x))
    test[c(FALSE, TRUE)] <- apply(test[c(FALSE, TRUE)], 2, function(x) f(x))
    

    这是可行的,因为 R 中的回收规则会导致例如c(TRUE, FALSE) 需要重复多次才能覆盖输入 test 数据框中的所有列。

    对于矩阵,我们需要在对矩阵进行子集化时使用drop=FALSE标志,以便在使用apply()时保持矩阵形式:

    test <- matrix(1:12, ncol = 4)
    test[,c(TRUE, FALSE)] <- apply(test[,c(TRUE, FALSE),drop=FALSE], 2, function(x) x+1)
    test
    
         [,1] [,2] [,3] [,4]
    [1,]    2    4    8   10
    [2,]    3    5    9   11
    [3,]    4    6   10   12
            ^         ^ ... these columns incremented by 1
    

    【讨论】:

    • 当我运行 test[c(TRUE, FALSE)]
    • @CuriousJorge-user9788072 查看更新后的答案。您可以在对矩阵进行子集化时使用drop=FALSE 标志,以在使用apply 时将其保持为矩阵形式。现在发生的事情是矩阵的子集被强制转换为一维整数向量,因此出现dim(X) 错误消息。
    • 我现在明白了,drop = FALSE。我一直在做出错误的假设,即由于 apply() 用于矩阵,它会保留矩阵形式而不是简化为一维向量。经验教训。
    【解决方案2】:

    您可以使用模%% 2

    odd <- !seq(ncol(test)) %% 2 == 0
    test[, odd] <- apply(test[, odd], 2, function(x) {return(x + 1)}) 
    #      [,1] [,2] [,3] [,4]
    # [1,]    2    4    8   10
    # [2,]    3    5    9   11
    # [3,]    4    6   10   12
    

    【讨论】:

    • 这段代码给了我一个 [2,2,4, 5,5,7, 8,8,10, 11,11,13] 的矩阵,而不是 [2,3, 4, 4,5,6, 8,9,10, 10,11,12] 我在找。它只需要为每个奇数列中的每个元素添加一个值 1。
    • @CuriousJorge-user9788072 只需将odd 移到逗号的另一边,请参阅编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多