【问题标题】:Why do I have to use assign() instead of eval(parse(text=())) in R为什么我必须在 R 中使用 assign() 而不是 eval(parse(text=()))
【发布时间】:2013-05-24 12:33:40
【问题描述】:

当我想使用循环将新值分配给多个数据帧时,就会出现问题。

我知道正确的方法是

for (df.name in c('df1', 'df2', 'df3')) {
  assign(df, new.value)
}

我的问题是,为什么我不能这样做

for (df.name in c('df1', 'df2', 'df3')) {
  eval(parse(text=df.name)) <- new.value
}

谢谢!

【问题讨论】:

    标签: r loops assign


    【解决方案1】:

    你可以使用 eval/parse:

    eval(parse(text= paste(df.name, "<- new.value")))
    

    你得到的错误,

    赋值目标扩展为非语言对象

    是因为 eval(parse(text=df.name)) 返回变量 df1,它不是要计算的 R 表达式。


    请记住,eval/parse 是黑暗的、危险的、魔法,会导致无法维护的僵尸代码。如果您能找到其他方式来编写代码,请选择它。


    如 cmets 中所述,如果您有多个具有相似属性的数据框,通常将它们作为列表使用会更容易。

    df_list <- list(df1 = df1, df2 = df2, df3 = df3)
    

    然后您可以使用lapply 循环操作每个数据帧,或者使用rbinddplyr::bind_rows 将它们组合成一个数据帧。

    【讨论】:

    • 啊!所以 eval(parse(text=()) 将返回一些将立即被评估的东西。我错误地认为这是一种在代码中将字符串转换为对象名称的方法。
    • +1 最后一句。如果向显然不知道有更好/更节省/更简单的方法(例如,使用列表)的人展示如何做到这一点,我很矛盾。它可能只是支持坏习惯。
    • 例如(根据@Roland 的评论),创建bigdf&lt;-list(df1=df1,df2=df2,... 并且对该列表的元素进行操作会很容易。
    • 谢谢!这对于为数据框上的新列分配值也很有用,而数据框名称和变量名称都可以是参数。
    猜你喜欢
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-10
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    相关资源
    最近更新 更多