【问题标题】:How to create new variable at the end of each loop iteration in R如何在 R 中的每个循环迭代结束时创建新变量
【发布时间】:2019-12-06 20:35:26
【问题描述】:

我正在尝试创建一个变量,它是 4 个其他变量的函数。我有以下代码:

set.seed(123)
iter <- 1000
group <- c('A','B','C','D','E','F')
for (i in group) {
  df <- df1[df1$group == i,]
  x_ <- vector(mode="numeric", length=1000)
  assign(eval(paste0("X_", i)), globalenv())   #This is the issue

  a <- rnorm(iter, mean=df$a, sd=df$sea)
  b <- rnorm(iter, mean=df$b, sd=df$seb)
  c <- rnorm(iter, mean=df$c, sd=df$sec)
  z <- rnorm(iter, mean=df$zbar, sd=df$se_z)

  X_[i] = (a + c*(z-df$zbar))/(-b)
}

我无法创建唯一的特定于组的变量(例如 X_A、X_B、...),并且我不确定为什么 -assign( )- 函数无法正常工作。数据框df1 有 6 行(每组一行),然后列数等于变量数加上组的字符串变量。我不想将这个新变量 X_[i] 附加到数据集,我只是想将它放在全局环境中。我认为问题在于我分配了变量的位置,但它没有生成数字变量 X。

df1 是一个包含a, sea, b, seb, c, sec, zbar, se_z 的 9 个变量的 6 个观察值的数据框。这些分别只是 a、b、c 和 z 的平均值和标准差。第 9 个变量是 group,其中包含 A、B、...、F。当我使用代码 df &lt;-df1[df1$group == i,] 时,我试图为每个组实体创建一个唯一的 X 变量。

【问题讨论】:

  • 你能准确地说出df1crop 是什么吗?如果df1 是数据框,还提供df1 的可重现示例
  • 我已经更新了问题,感谢您指出这一点
  • 这在 R 中是一种糟糕的设计模式。与其将数据粘贴到变量名称中,不如将值存储在命名列表中。这使得在 R 中处理事情变得更加容易。get()/assign() 通常应该避免

标签: r loops dataframe for-loop


【解决方案1】:

试试这样的:

dynamicVariableName <- paste0("X_", i)
assign(dynamicVariableName, (a + c*(z-df$zbar))/(-b))

【讨论】:

    【解决方案2】:

    除了@ErrorJordan 的答案,您可以这样编写循环:

    set.seed(123)
    iter <- 1000
    group <- c('A','B','C','D','E','F')
    for(i in group)
    {
      df <- df1[df1$group == i,]
    
      a <- rnorm(iter, mean=df$a, sd=df$sea)
      b <- rnorm(iter, mean=df$b, sd=df$seb)
      c <- rnorm(iter, mean=df$c, sd=df$sec)
      z <- rnorm(iter, mean=df$zbar, sd=df$se_z)
    
      X <- (a + c*(z-df$zbar))/(-b)
      assign(paste0("X_",i),X,.GlobalEnv)
    }
    

    正如@MrFlick 所建议的,您还可以将数据存储到列表中,为此您只需修改循环以获取:

    set.seed(123)
    iter <- 1000
    group <- c('A','B','C','D','E','F')  
    X = vector("list",length(group))
    names(X) = group
    for(i in 1:length(group))
    {
      df <- df1[df1$group == group[i],]    
      a <- rnorm(iter, mean=df$a, sd=df$sea)
      b <- rnorm(iter, mean=df$b, sd=df$seb)
      c <- rnorm(iter, mean=df$c, sd=df$sec)
      z <- rnorm(iter, mean=df$zbar, sd=df$se_z)
    
      X[[i]] <- (a + c*(z-df$zbar))/(-b)
    }
    

    df1 数据帧

    df1 = data.frame(a = c(1:6),
                     b = c(1:6),
                     c = c(1:6),
                     zbar = c(1:6),
                     sea = rep(1,6),
                     seb = rep(1,6),
                     sec = rep(1,6),
                     se_z = rep(1,6),
                     group = group)
    

    【讨论】:

      【解决方案3】:

      解析你想要做的事情有点困难,但我假设它是这样的

      group 中的每个值创建一个名为X_AX_B、...的对象(在全局环境中)

      对于每个对象,为其分配值(a + c*(z-df$zbar))/(-b)

      我认为这应该为你做到这一点:

      set.seed(123)
      group <- c('A','B','C','D','E','F')
      for (i in group) {
        df <- df1[df1$group == i,]
      
        a <- rnorm(iter, mean=df$a, sd=df$sea)
        b <- rnorm(iter, mean=df$b, sd=df$seb)
        c <- rnorm(iter, mean=df$c, sd=df$sec)
        z <- rnorm(iter, mean=df$zbar, sd=df$se_z)
      
        assign(paste0("X_", i), (a + c*(z-df$zbar))/(-b), globalenv())
      }
      

      请注意,在您给出的代码示例中,命令iter &lt;- 1000 无效,命令x_ &lt;- vector(mode="numeric", length=1000) 也无效。我的意思是,您制作了这些对象,但随后从未在任何进一步的计算中使用它们。如果这些命令应该做一些有意义的事情,我需要你的帮助来解释它们的预期目的。

      【讨论】:

      • Iter 在每个随机变量生成开始时用作观察次数,但未使用向量 one,但感谢指出
      猜你喜欢
      • 2019-01-19
      • 1970-01-01
      • 2015-11-10
      • 2020-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-30
      • 1970-01-01
      相关资源
      最近更新 更多