【问题标题】:How to handle R eval with transmute?如何使用 transmute 处理 R eval?
【发布时间】:2020-05-26 10:26:14
【问题描述】:

我对 R 很陌生。我正在尝试将一些列聚合到一个新列中。因为只有聚合列必须保存到 DF,所以我使用 transmute。

因为列名可能不同,所以我试图连接一些字符串来制作一段代码,然后使用 parse 和 eval 来处理这段代码。

我整理的部分是:

transmute("aggr1" = as.numeric(val1) + as.numeric(val2), "aggr2" = as.numeric(val3) + as.numeric(val4))

如果我像这样制作一个新的数据框,它会完美运行:

data_aggr <- df %>%
  transmute("aggr1" = as.numeric(val1) + as.numeric(val2), "aggr2" = as.numeric(val3) + as.numeric(val4))

但是如果我放在一起的字符串看起来像:

composed = "transmute(\"aggr1\" = as.numeric(val1) + as.numeric(val2), \"aggr2\" = as.numeric(val3) + as.numeric(val4))"

然后我使用:

data_aggr <- df %>%
  eval(parse(text=composed))

它不会工作。我得到错误:

error in mutate(.data, !!!dots)

我的解决方案可行吗?我做错了吗?

【问题讨论】:

  • 您到底想完成什么?如果您展示实际问题,我们可能会向您展示一种可行的方法。连接字符串来创建代码片段绝对是错误的做法!
  • 嗨康拉德,我正在尝试对列进行聚合。用户可以选择 (a) 聚合列的新名称和 (b) 哪些列应该在聚合中。因此,如果 csv 中的用户给出例如 aggr1, val1, val2 那么应该有一个新列 aggr1 它是 val1 的聚合和 val2。因为用户必须能够更改 csv 文件,所以我认为这是要走的路。

标签: r eval


【解决方案1】:

作为一般规则您几乎永远不会希望在常规代码中使用 parseeval - 事实上,它们的存在应该是一个警告,即你'重新错误地思考问题。这些是用于低级 R 编程的专用工具,在分析代码中应该完全不存在。

首先,在您的代码中,造成混淆的一个可能原因是在列名周围使用双引号,因此您认为它们是字符串。事实并非如此! R 在几个地方默默地接受字符串文字而不是变量名,并且将它们视为变量名

所以你的初始代码实际上相当于

transmute(aggr1 = as.numeric(val1) + as.numeric(val2), aggr2 = as.numeric(val3) + as.numeric(val4))

不带引号,这种区别对于理解正在发生的事情至关重要。


现在,如何概括这一点,以便您可以实际上使用不同的列名(即计算值)?简而言之,您需要在列名前使用!!,并使用:= 而不是=

!! 导致 dplyr 将列名解释为计算值,并使用 := 而不是 = 防止 R 将值视为函数调用参数名称(它可以解决 R 的限制,因为 !! x = y 会语法无效)。

例如:

prefix = 'aggr'
data_aggr = df %>%
  transmute(
    !! paste0(prefix, 1) := as.numeric(val1) + as.numeric(val2),
    !! paste0(prefix, 2) := as.numeric(val3) + as.numeric(val4)
  )

如何精确计算列名显然取决于您的具体问题。

如何动态调用 dplyr 函数的详细信息在小插图programming with dplyr 中进行了说明。

【讨论】:

    猜你喜欢
    • 2019-01-06
    • 2017-01-19
    • 2014-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    相关资源
    最近更新 更多