【问题标题】:dplyr 'rename' standard evaluation function not working as expected?dplyr 'rename' 标准评估功能没有按预期工作?
【发布时间】:2019-05-07 17:18:16
【问题描述】:

更新:从下面对这篇文章的评论来看,这现在按预期工作,没有我在此处列出的问题。

下面是使用来自 dplyr 的 rename_ 的玩具示例。我期望能够使用下面的第二个示例将列名更改回原来的名称,但我猜函数参数评估规则在某种程度上阻止了它按我想的方式工作。使用原始 plyr 包 rename 函数(以及使用基本包 names 函数)有一个简单的解决方法,但我觉得我缺少一个 dplyr 解决方案。

我有一个如下所示的解决方法,但我欢迎第二个示例的 dplyr 解决方案按我的预期工作,或者解释为什么我不应该期望它按我希望的方式工作。

谢谢你, 马特

编辑:我在下面添加了一个示例,使用rename_ 来完成这项工作,但很复杂。我假设如果 Hadley 在下面提到的错误得到修复,这将如下所示。但在那之前,我的尴尬方式确实如此,但使用标准的plyr 方法可能会更好。最后还添加了基本 R 技术,例如完整性。

library(plyr)
library(dplyr)

# dataframe to operate on
dat <- data_frame(a=1, b=1)

# identifier with string of column name in dat
x <- "a"


# Renaming using standard evaluation this way works
dat %>%
    rename_("new" = x)
# Source: local data frame [1 x 2]
# 
#   new b
# 1   1 1


# But changing it back does not
# I expect "a" to be the name, not the identifier x
dat %>%
    rename_("new" = x) %>%
    rename_(x = "new")
# Source: local data frame [1 x 2]
# 
#   x b
# 1 1 1


# This works, but seems really awkward...
dat %>%
    rename_("newname" = x) %>%
    do(do.call(rename_, setNames(list(., "newname"), c(".data", x))))

# Source: local data frame [1 x 2]
# 
#   a b
# 1 1 1


# This works fine
dat %>%
    rename_("new" = x) %>%
    plyr::rename(c("new" = x))
# Source: local data frame [1 x 2]
# 
#   a b
# 1 1 1


# Base R way
datrn <- dat %>%
    rename_("newname" = x)
names(datrn)[names(datrn) == "newname"] = x
datrn
# Source: local data frame [1 x 2]
# 
#   a b
# 1 1 1

【问题讨论】:

标签: r dplyr


【解决方案1】:

有几件事让这很痛苦:

  1. c(x = "new")c("x" = "new") 相同,而不是相反 的c(new = x)

  2. 你可以用setNames(x, "new")构造你想要的向量, 但是……

  3. 我忘记将 .dots 参数添加到 rename_(错误报告在 https://github.com/hadley/dplyr/issues/708) 所以你不能这样做:

    rename_(dat, .dots = setNames(x, "new"))
    

    您需要使用do.call:

    do.call(rename_, c(list(quote(dat)), list(setNames(x, "new"))))
    

【讨论】:

  • 所以,我试图让do.call 示例工作,但我没有让它工作。不确定如何更改以将 dat 对象合并到该调用中,因为调用本身没有引用它。
  • 而且,在尝试setNames 的各种方式中,我收到以下类型的错误:All arguments to rename must be named.FALSE
  • @mpettis do.call 调用应该会好一点
  • 我尝试了这种变化,我得到了&gt; do.call(rename_, list(dat, setNames(x, "new"))) Error in rename_vars_(names(.data), dots) : All arguments to rename must be named.FALSE
  • 这是do.call 结构,我能够工作:do.call(rename_, setNames(list(datrn, "new"), c(".data", x)))
【解决方案2】:

在我的 Rstudio 中,我定义:

x <- 'myname'
dat <- data.frame(yes=1, no=2)

我想将变量名从 yes 更改为 myname

它不起作用:

rename_(dat, .dots = setNames(x, "yes"))

但这有效:

rename_(dat, .dots = setNames("yes", x))

rename_(dat, .dots = setNames("yes", paste(x) ))

【讨论】:

    猜你喜欢
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 2015-02-23
    • 1970-01-01
    相关资源
    最近更新 更多