【问题标题】:How to do this without a for loop如何在没有 for 循环的情况下执行此操作
【发布时间】:2015-02-12 08:01:14
【问题描述】:

以下代码使数据框充满 0,列和行标签为数字:

#make blank data frame, label the columns and rows
data <- data.frame(matrix(0, ncol = 4, nrow = 4)) 
colnames <- seq(from = 1, to = 4, by = 1)
names(data)<- sprintf("%.0f", colnames)
rownames <- seq(from=3, to=12, by=3)
rownames(data) <- sprintf("%.0f", rownames)

我的问题是,鉴于上述数据框,我如何填写数据框,每个单元格取行标签乘以列标签的值,而不是像我在代码中那样使用 for 循环跟随。我想知道如何使用矢量化方法来做到这一点,而不必遍历每个单独的单元格。

for(i in 1:nrow(data)){
    for(j in 1:ncol(data)){
        data[i,j] <- as.numeric(rownames(data)[i])*as.numeric(colnames(data)[j])
    }
}

【问题讨论】:

    标签: r for-loop vector dataframe row


    【解决方案1】:

    您可以将rownamescolnames 向量转换为numerics,然后像这样获取它们的外积:

    > as.numeric(rownames(data)) %o% as.numeric(colnames(data))
         [,1] [,2] [,3] [,4]
    [1,]    3    6    9   12
    [2,]    6   12   18   24
    [3,]    9   18   27   36
    [4,]   12   24   36   48
    

    并根据需要进行适当的修改:

    data2 <- data.frame(
      as.numeric(rownames(data)) %o% 
      as.numeric(colnames(data)))
    names(data2) <- names(data)
    ##
    > data2
       1  2  3  4
    1  3  6  9 12
    2  6 12 18 24
    3  9 18 27 36
    4 12 24 36 48
    

    %o% 有一个(不太紧凑的)版本,它不会限制您使用外部产品

    outer(as.numeric(rownames(data)),
          as.numeric(colnames(data)),
          FUN=function(x,y){ x*(2/3) + y/3 })
             [,1]     [,2] [,3]     [,4]
    [1,] 2.333333 2.666667    3 3.333333
    [2,] 4.333333 4.666667    5 5.333333
    [3,] 6.333333 6.666667    7 7.333333
    [4,] 8.333333 8.666667    9 9.333333
    

    outer的默认情况下,FUN="*",相当于使用%o%

    【讨论】:

    • 聪明的解决方案。如果我需要执行列名和行名的另一个功能怎么办?例如,如果我定义了一个函数 a(x,y),我该如何为这个函数输入正确的行名和列名?
    • 很难说,因为解决方案会因a(x,y) 的不同而有所不同;不过,几乎肯定可以采用矢量化方法。一般来说,mapply 可能是一个很好的起点——它是否是 最佳 方法将取决于特定的操作。
    • 好的。我想我想了想之后就明白了。这只是您答案的变体。谢谢!
    • 对不起-也许不是。假设函数定义为:a(x,y) &lt;- ((2*x)/3) + ((3*y)/9)。这是伪代码,顺便说一句。
    猜你喜欢
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 2013-02-16
    • 2021-11-11
    • 1970-01-01
    • 2020-09-16
    • 2021-05-13
    • 1970-01-01
    相关资源
    最近更新 更多