Стандартная функция оценки dplyr 'rename' работает не так, как ожидалось?

ОБНОВЛЕНИЕ. Из комментариев ниже этого сообщения это работает, как и ожидалось, без проблем, которые я изложил здесь.

Ниже приведен пример игры с использованием rename_ из dplyr. Я ожидал, что смогу изменить имя столбца на его исходное имя, используя второй пример ниже, но я предполагаю, что правила оценки аргументов функции каким-то образом мешают ему работать так, как я думаю. Существует простой способ обхода проблемы с использованием исходной функции plyr package rename (а также с использованием функции базового пакета names), но у меня есть ощущение, что мне не хватает решения dplyr.

У меня есть обходное решение, как показано ниже, но я бы приветствовал как решение dplyr во втором примере, работающем, как я ожидаю, так и объяснение того, почему я не должен ожидать, что он будет работать так, как я этого хочу.

Спасибо, Matt

EDIT: я добавил пример ниже, используя rename_, чтобы сделать эту работу, но сложна. Я предполагаю, что ошибка, о которой упоминается Хэдли ниже, будет исправлена, это будет работать, как показано ниже. Но до сих пор мой неловкий способ, но, вероятно, лучше использовать стандартный метод 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

Ответ 1

Есть несколько вещей, которые делают это болезненным:

  • c(x = "new") совпадает с c("x" = "new"), а не наоборот c(new = x).

  • Вы можете построить нужный вектор с помощью setNames(x, "new"), но...

  • Я забыл добавить аргумент .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"))))
    

Ответ 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) ))