UPDATE: From comment below on this post, this is now working as expected, without the issues I laid out here.
Below is a toy example of using rename_
from dplyr. I was expecting to be able to change the column name back to it's original name using the second example below, but I'm guessing that function argument evaluation rules are somehow preventing it from working the way I think. There is an easy workaround using the original plyr package rename
function (as well as using the base package names
function), but I have a feeling I'm missing a dplyr solution to this.
I have a workaround as shown below, but I'd welcome both a dplyr solution to the second example working as I expect, or an explanation of why I shouldn't expect it to work the way I want it to.
Thank you, Matt
EDIT: I added an example below using rename_
to make this work, but is complicated. I assume if the bug that Hadley refers to below gets fixed, this will work as he shows below. But until then, my awkward way does, but it is probably better to use the standard plyr
method. Also added base R technique at end for example completeness.
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
There are a few thing that make this painful:
c(x = "new")
is the same as c("x" = "new")
, and not the opposite
of c(new = x)
.
You can construct the vector you want with setNames(x, "new")
,
but...
I forgot to add the .dots
argument to rename_
(bug report at
https://github.com/hadley/dplyr/issues/708) so you can't do:
rename_(dat, .dots = setNames(x, "new"))
Instead you need to use do.call
:
do.call(rename_, c(list(quote(dat)), list(setNames(x, "new"))))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With