【问题标题】:Apply R function to multiple objects and rewrite object将R函数应用于多个对象并重写对象
【发布时间】:2017-03-07 01:34:15
【问题描述】:

我正在尝试执行以下操作:

  • 定义一个函数,该函数根据数据框中的现有列创建附加列
  • 将上述函数应用于多个对象(数据帧),重写原始数据帧

比如说函数是 iris 中的 Petal.Length 除以 Petal.Width。

divvy <- function(mydataframe){mydataframe$divvy <- mydataframe$Petal.Length/mydataframe$Petal.Width}

这部分很简单。

现在假设我有三个(或三千个)虹膜数据框:

iris2 <- iris
iris4 <- iris
iris5 <- iris

我要避免的是:

iris <- divvy(iris)
iris2 <- divvy(iris2)
iris4 <- divvy(iris4)
iris5 <- divvy(iris5)

我拥有的 iris 数据帧的数量是无穷大

...类似于

lapply(c(iris,iris2,iris4,iris4), function(x) divvy(x))

最后是 iris、iris2、iris4 和 iris5 具有新的 divvy 列。我该怎么做呢?

请注意:我不想创建一个包含所有虹膜的元对象。

【问题讨论】:

    标签: r


    【解决方案1】:

    我们可以使用data.table 来做到这一点:

    library(data.table)

     divvy <- function(x){x[,divvy := Petal.Length/Petal.Width]}
    
    iris2 <- data.table(iris)
    iris4 <- data.table(iris)
    iris5 <- data.table(iris)
    
    test <- lapply(list(iris2,iris4,iris5), function(x) divvy(x))
    

    测试看起来像这样(仅显示列表的前 2 个元素):

    > test
    [[1]]
         Sepal.Length Sepal.Width Petal.Length Petal.Width   Species    divvy
      1:          5.1         3.5          1.4         0.2    setosa 7.000000
      2:          4.9         3.0          1.4         0.2    setosa 7.000000
      3:          4.7         3.2          1.3         0.2    setosa 6.500000
      4:          4.6         3.1          1.5         0.2    setosa 7.500000
      5:          5.0         3.6          1.4         0.2    setosa 7.000000
     ---                                                                     
    146:          6.7         3.0          5.2         2.3 virginica 2.260870
    147:          6.3         2.5          5.0         1.9 virginica 2.631579
    148:          6.5         3.0          5.2         2.0 virginica 2.600000
    149:          6.2         3.4          5.4         2.3 virginica 2.347826
    150:          5.9         3.0          5.1         1.8 virginica 2.833333
    
    [[2]]
         Sepal.Length Sepal.Width Petal.Length Petal.Width   Species    divvy
      1:          5.1         3.5          1.4         0.2    setosa 7.000000
      2:          4.9         3.0          1.4         0.2    setosa 7.000000
      3:          4.7         3.2          1.3         0.2    setosa 6.500000
      4:          4.6         3.1          1.5         0.2    setosa 7.500000
      5:          5.0         3.6          1.4         0.2    setosa 7.000000
     ---                                                                     
    146:          6.7         3.0          5.2         2.3 virginica 2.260870
    147:          6.3         2.5          5.0         1.9 virginica 2.631579
    148:          6.5         3.0          5.2         2.0 virginica 2.600000
    149:          6.2         3.4          5.4         2.3 virginica 2.347826
    150:          5.9         3.0          5.1         1.8 virginica 2.833333
    

    编辑***响应 OP 更新问题规范:

    你可以试试这个:

    for(i in c("iris2", "iris4", "iris5")){
      x <- divvy(get(i))
      assign(paste0(i,"divvied"), x)
    }
    

    虽然我建议反对assign,尤其是对于很多对象。您可以从我在答案前半部分创建的test 列表中提取元素,您仍然会得到相同的答案,只是更简洁一些。

    代码所做的是将iris 数据表作为字符串拉入,然后使用get 读取它们。这将传递给您的 divvy 函数,创建一个 data.table x。然后我使用assign创建后缀为divvied的data.table。

    【讨论】:

    • 好的,我不确定如何澄清我的问题以明确这一点:问题不在于定义函数,这是您的数据表实现很好地解决的问题。我实际上询问/试图解决的问题是不必生成包含虹膜数据帧列表的新测试对象 - 我想修改虹膜。
    • 澄清了问题中的措辞,以使这一点更清楚
    • 这是否意味着您想在您的环境中创建“无限”对象?
    • 这意味着,是的,我的环境中已经有无穷大的对象,我只想批量修改它们。实际上,我通常在 12 - 20 个对象上执行此操作,因此实际上不是无穷大 - 但我希望能够编写一行代码来定义函数,并编写一行代码来将其应用于所有数据集。
    猜你喜欢
    • 2016-08-11
    • 2017-11-04
    • 2020-08-23
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 2012-02-14
    相关资源
    最近更新 更多