【问题标题】:automate repeating models with different data forloop in R使用 R 中的循环自动创建具有不同数据的模型
【发布时间】:2021-07-02 08:35:01
【问题描述】:

我需要在同一个模型上运行大量复制,但在每次迭代时将不同的数据循环到其中。

例如

db1 <- mtcars
db2 <- mtcars
db3 <- mtcars

for(i in 1:db) {
  # keep model structure but alternate the data
  lm(mpg ~ wt, data = db[i])
}

我需要创建一个 for 循环或函数,可以在 db1 上运行模型,然后换入 db2 并运行相同的模型。我还需要将它们作为单独的对象存储在我的 R 环境中,例如lm1(用于 db1)和 lm2(用于 db2)

请有人帮我自动化这个。

谢谢

【问题讨论】:

    标签: r function for-loop automation iteration


    【解决方案1】:

    创建一个数据帧列表,而不是将单个数据帧作为对象创建,因为循环 db1、db2、db3 更难,而不是创建更容易在列表中循环的数据帧。这里创建的 dfs 基本上是您可以在其上创建模型的数据框列表。现在,我在这里使用 mtcars 创建了随机数据集,在您的情况下,您可能已经将数据集保存为 db1、db2 或 db3,因此您可以执行以下任一操作:

    a) dfs = list(db1, db2, db3) 将此 dfs 与 lapply 一起使用,如下所示:mymodels &lt;- lapply(dfs, function(x)lm(mpg ~ wt, data=x))

    b) dfs &lt;- mget(ls(pattern='^db\\d+'), envir = globalenv()) ,在这里你把你的数据模式放在模式里面,在这种情况下,它以 db 单词开头并以数字结尾,现在使用与上面类似的 lapply:mymodels &lt;- lapply(dfs, function(x)lm(mpg ~ wt, data=x))

    我从 mtcars 数据中给出了一个示例,使用随机选择的行来提出一种方法。

    # Creating a list of data-frames randomly
    # Using replicate function n(3) times here and picking 80% of data randomly, using seed value 1 for reproducibility
    
    set.seed(1)
    n <- 3
    prop = .8
    
    dfs <- lapply(data.frame(replicate(n, sample(1:nrow(mtcars), prop*nrow(mtcars)))), function(x)mtcars[x,])
    ## replicate function here replicates sample command n number of times and create a matrix of indexs of rows taken as different data points from mtcars dataset
    
    mymodels <- lapply(dfs, function(x)lm(mpg ~ wt, data=x)) #mymodels is your output
    

    输出

    $X1
    
    Call:
    lm(formula = mpg ~ wt, data = x)
    
    Coefficients:
    (Intercept)           wt  
      38.912167    -5.874795  
    
    
    $X2
    
    Call:
    lm(formula = mpg ~ wt, data = x)
    
    Coefficients:
    (Intercept)           wt  
      37.740419    -5.519547  
    
    
    $X3
    
    Call:
    lm(formula = mpg ~ wt, data = x)
    
    Coefficients:
    (Intercept)           wt  
      39.463332    -6.051852  
    

    【讨论】:

    • 两个非常有用的解决方案!非常感谢。非常有效。
    【解决方案2】:

    我用来做这样的事情的方法是在数据框列表上使用地图函数。我的首选方法是使用嵌套数据框,其中我们有一列用于数据框名称、数据框,并且我们添加了一个线性模型列。

    我使用 map 函数在下面编写了一个版本,该函数采用我们的数据帧向量并将 lm 应用于每个条目。

    library(tidyverse)
    
    db1 <- mtcars
    db2 <- mtcars
    db3 <- mtcars
    
    # Place dataframes in a liset (note do not use c() to put dfs into an array)
    a <- list(db1, db2 , db3)
    
    # Construct our dataframe
    df <- tibble(entry = 1:3, dataframes = a)
    
    df %>% 
      # Map the lm function to all of the dataframes
      mutate(lm = map(dataframes, ~lm(mpg~wt, data = .x)))
    #> # A tibble: 3 x 3
    #>   entry dataframes          lm    
    #>   <int> <list>              <list>
    #> 1     1 <df[,11] [32 x 11]> <lm>  
    #> 2     2 <df[,11] [32 x 11]> <lm>  
    #> 3     3 <df[,11] [32 x 11]> <lm>
    

    reprex package (v2.0.0) 于 2021-04-06 创建

    仅使用列表的更直观的方法如下:

    (请注意,某些信息,即对 lm 的调用丢失了)

    library(tidyverse)
    
    db1 <- mtcars
    db2 <- mtcars
    db3 <- mtcars
    
    a <- list(db1, db2 , db3)
    
    b <- rep(list(), 3)
    
    for(i in 1:3) {
      b[i] <- lm(mpg~wt, data = a[[i]])
    }
    #> Warning in b[i] <- lm(mpg ~ wt, data = a[[i]]): number of items to replace is
    #> not a multiple of replacement length
    b
    #> [[1]]
    #> (Intercept)          wt 
    #>   37.285126   -5.344472 
    #> 
    #> [[2]]
    #> (Intercept)          wt 
    #>   37.285126   -5.344472 
    #> 
    #> [[3]]
    #> (Intercept)          wt 
    #>   37.285126   -5.344472
    

    reprex package (v2.0.0) 于 2021-04-06 创建

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-21
      • 1970-01-01
      • 2020-12-21
      • 2018-09-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多