tchakravarty
tchakravarty

Reputation: 10964

dplyr: Renaming variables with rename_

I am trying to rename several variables in a chain:

df_foo = data_frame(
  a.a = 1:10,
  "b...b" = 1:10,
  "cc..d" = 1:10
)

df_foo %>% 
  rename_(
    .dots = setNames(
      names(.),
      gsub("[[:punct:]]", "", names(.)))
  )

This works fine, but when there is a space in the name of one of the variables:

df_foo = data_frame(
  a.a = 1:10,
  "b...b" = 1:10,
  "c c..d" = 1:10
)

df_foo %>% 
  rename_(
    .dots = setNames(
      names(.),
      gsub("[[:punct:]]", "", names(.)))
  )

I get this error:

Error in parse(text = x) : <text>:1:3: unexpected symbol
1: c c..d
      ^

I am not sure where this stems from since when I run gsub directly:

setNames(
      names(df_foo),
      gsub("[[:punct:]]", "", names(df_foo)))

I do not get an error. Not sure what is going on here.


This is now raised as issue #2391 on the dplyr GH issues page.

Upvotes: 1

Views: 1159

Answers (1)

Axeman
Axeman

Reputation: 35307

In general: I strongly suggest you never use variable names with spaces. They are a pain and will often cause more trouble than they are worth.

Here is the cause of this error.

rename_ dispatches to dplyr:::rename_.data.frame. First line of that function is:

dots <- lazyeval::all_dots(.dots, ...)

That lazyeval function will then call lazyeval::as.lazy_dots, which uses lazyeval::as.lazy, which itself uses lazyeval:::as.lazy.character which calls lazy_(parse(text = x)[[1]], env). Now, parse() expects valid R expression as its text argument:

text: character vector. The text to parse. Elements are treated as if they were lines of a file. (from help("parse"))

This is why rename_ doesn't seem to like character vectors with spaces and we get "Error in parse(text = x)":

lazyeval:::as.lazy(names(df_foo)[2])
<lazy>
  expr: b...b
  env:  <environment: base>
lazyeval:::as.lazy(names(df_foo)[3])
Error in parse(text = x) : <text>:1:3: unexpected symbol
1: c c..d
      ^

I'm not aware of a solution, other then just using base for this simple renaming.

Upvotes: 3

Related Questions