【问题标题】:Looping in R to create transformed variables在 R 中循环以创建转换后的变量
【发布时间】:2015-09-15 20:07:43
【问题描述】:

我有一个包含 80 个变量的数据集,我想遍历其中 50 个变量的子集并构造返回值。我有一个要为其构造返回的变量的名称列表,并且正在尝试使用 dplyr 命令 mutate 在循环中构造变量。具体我的代码是:

for (i in returnvars) {
   alldta <- mutate(alldta,paste("r",i,sep="") = (i - lag(i,1))/lag(i,1))}

returnvars 是我的列表,alldta 是我的数据集。当我只用一个“i”值在循环外运行这段代码时,它工作正常。代码如下所示:

alldta <- mutate(alldta,rVar = (Var- lag(Var,1))/lag(Var,1))

但是,当我在循环中运行它时(例如,尝试为 50 个不同的变量执行前一行代码 50 次),我收到以下错误:

Error: unexpected '=' in:
"for (i in returnvars) {
alldta <- mutate(alldta,paste("r",i,sep="") ="

我不确定为什么会出现这个问题。我已经研究了很多方法来尝试做到这一点,并尝试了使用 lapply 的解决方案,但没有成功。

任何帮助将不胜感激!如果还有一种简单的方法可以使用其中一个应用命令来做到这一点,那就太好了。我没有提供数据集,因为我的问题不是特定于数据的,我只是想了解,作为一个相对的 R 初学者,如何一次构造许多转换后的变量并将它们添加到我的数据框中。

编辑:根据弗兰克的评论,我将代码更新为以下内容:

for (i in returnvars) {
   varname <- paste("r",i,sep="")
   alldta <- mutate(alldta,varname = (i - lag(i,1))/lag(i,1))}

这修复了之前的错误,但我仍然没有正确引用变量,所以我得到了错误

Error in "Var" - lag("Var", 1) : 
non-numeric argument to binary operator 

我假设是因为 R 将我的变量名 Var 视为字符串,而不是变量。我将如何正确引用我的数据集 alldta 中的变量?我试过 get(i) 和 alldta$get(i),都没有成功。

相对于使用循环,我仍然对更多 R 风格的方式来完成整个过程持开放态度(并且积极好奇)。

【问题讨论】:

  • 欢迎来到 SO。首先你应该阅读here关于如何提出一个好问题;一个好的问题有更好的变化需要解决,你会得到帮助。另一方面,阅读this 也不错。它解释了如何在 R 中创建一个可重现的示例。通过为您的数据片段提供所需的输出以及您迄今为止尝试过的事情来帮助用户帮助您。
  • 看看这个问题:stackoverflow.com/questions/26003574/… 你得到错误是因为你不能在= 的左边构造你自己的变量名(既不在mutate 内,也不在R 中的任何其他地方)。
  • 这是一个有用的评论@Frank,谢谢!我将更新上面的代码 - 它仍然不起作用,但现在问题更多的是来自循环的变量引用,而不是我之前收到的错误。
  • 如果您使用 mutate_() 并构建整个调用,您可以构建自己的 varname,例如 mutate_(alldta, sprintf("r%s = (%s - lag(%s,1))/lag(%s,1))", i, i, i, i))。 (我可能错过了一个括号——也许有比i, i, i, i 更漂亮的方法。)
  • 一个笨拙的解决方法可能是select 你的列,mutate 他们通过mutate_each 然后在命名后将它们绑定回原来的:alldta %&gt;% select(one_of(returnvars)) %&gt;% mutate_each(funs( (. - lag(.))/lag(.))) %&gt;% setNames(paste0("r", names(.))) %&gt;% bind_cols(alldta, .)

标签: r loops dplyr


【解决方案1】:

在循环中使用 mutate 也可能不是一个好主意。我不确定 mutate 是否会复制数据帧,但在循环内增长数据帧通常不是一个好习惯。而是使用输出创建一个单独的数据框,然后根据您的逻辑命名列。

result = do.call(rbind,lapply(returnvars,function(i) {...})
names(result) = paste("r",returnvars,sep="")

【讨论】:

  • 这看起来像是我想要的那种解决方案,但这并不完全适合我。您是否可以针对我的具体情况更新您的答案,其中函数是: (i - lag(i,1))/lag(i,1)) 并且 return vars 是 alldta 中的变量名列表(尽管没有前面的 alldta$,所以我需要弄清楚如何告诉 R)
【解决方案2】:

在玩了更多之后,我发现(感谢弗兰克的建议),以下工作:

extended <- alldta # Make a copy of my dataset
for (i in returnvars) {
  varname <- paste("r",i,sep="")
  extended[[varname]] = (extended[[i]] - lag(extended[[i]],1))/lag(extended[[i]],1)}

这仍然不是很 R 风格,因为我正在使用循环,但对于仅重复大约 50 次的任务,这应该不是一个大问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多