Dplyr 'Rename' Standard Evaluation Function Not Working as Expected

Rename() function in R not working with Dplyr pipe inside for loop

Note that you have a data-variable in a function argument (i.e. an env-variable that holds a promise, you need to embrace the argument by surrounding it in doubled braces. This is called [INDIRECTION], which is a glue syntax.

If you want to use the names of variables in the output, you can use glue syntax in conjunction with :=

Therefore you get

rename({{asset}} = price)

Check here for more information

Non-standard evaluation and quasiquotation in dplyr() not working as (naively) expected

So, I've realized that what I was struggling with in this question (and many other probelms) is not really quasiquotation and/or non-standard evaluation, but rather converting character strings into object names. Here is my new solution:

letrs_top.df <- letrs_count.df %>%
top_n(5, get(count_colname))

dplyr rename not working with regular expression

select is already renaming them for you. You can add everything() to the call in order to get the rest of the columns

select(iris, petal = starts_with("Petal"), everything())
# petal1 petal2 Sepal.Length Sepal.Width Species
# 1 1.4 0.2 5.1 3.5 setosa
# 2 1.4 0.2 4.9 3.0 setosa
# 3 1.3 0.2 4.7 3.2 setosa
# 4 1.5 0.2 4.6 3.1 setosa
# 5 1.4 0.2 5.0 3.6 setosa
# 6 1.7 0.4 5.4 3.9 setosa
# 7 1.4 0.3 4.6 3.4 setosa
# 8 1.5 0.2 5.0 3.4 setosa
# 9 1.4 0.2 4.4 2.9 setosa
...

Replacement for rename in dplyr

dplyr version 0.3 added a new rename() function that works just like plyr::rename(), but with the old and new names switched:

df <- rename(df, new_name = old_name)

renaming column names with variable

Credit and further information in this post for this dplyr 'rename' standard evaluation function not working as expected?

Your code:

newName = paste0('nameY', 2017)
iris %>%
rename(newName = Petal.Length) %>%
head(2)

Solution:

iris %>% 
rename_(.dots = setNames("Petal.Length",newName)) %>%
head(2)

Output:

  Sepal.Length Sepal.Width nameY2017 Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa

R dplyr: rename variables using string functions

I think you're looking at the documentation for plyr::rename, not dplyr::rename. You would do something like this with dplyr::rename:

iris %>% rename_(.dots=setNames(names(.), tolower(gsub("\\.", "_", names(.)))))

dplyr filter not working as expected in function with same argument names

dplyr and friends1 are smart, but they cannot differentiate between the two references to gear (and carb). For instance, in gear == as.numeric(gear), you intend the first to refer to gear within the frame and the second to refer to the function argument, but in these functions, the first match of gear (to within the frame, within the function environment, within the enclosing environments) wins and is used for all references. In this case, they both match the column of the frame, and are therefore always TRUE (in this example).

Try:

function(carb., gear.) {
mtcars %>% filter(gear == as.numeric(gear.),
carb == as.numeric(carb.)) %>%
jsonlite::toJSON()

}

This has the unfortunate side-effect that the API arguments are less aesthetic. So if you want to preserve the way they look (or there are external motivators to keeping them as-is), then do a quick reassignment.

function(carb, gear) {
c. <- carb
g. <- gear
mtcars %>%
filter(gear == as.numeric(g.),
carb == as.numeric(c.)) %>%
jsonlite::toJSON()
}

Side note: I find it useful at times to implement permissive filtering, where an omitted (or intentionally-null) argument means no filtering.

function(carb = NA, gear = NA) {
c. <- carb
g. <- gear
mtcars %>%
filter(is.na(g.) | gear == as.numeric(g.),
is.na(c.) | carb == as.numeric(c.)) %>%
jsonlite::toJSON()
}

Another side note: is there a reason you are doing a double JSON here? For instance, I'm seeing:

$ curl -s localhost:8000/test2?gear=4
"[{\"mpg\":21,\"cyl\":6,\"disp\":160,\"hp\":110,\"drat\":3.9,\"wt\":2.62,\"qsec\":16.46,\"vs\":0,\"am\":1,\"gear\":4,\"carb\":4},...]"

which is returning a long string (note the quotes). Many parsers will see that as a string and preserve it. (For instance, piping curl ... | jq . does not break-open the json as it should, it just returns the literal string.)

Instead, if you remove the toJSON, you see:

$ curl -s localhost:8000/test2?gear=4
[{"mpg":21,"cyl":6,"disp":160,"hp":110,"drat":3.9,"wt":2.62,"qsec":16.46,"vs":0,"am":1,"gear":4,"carb":4},...]

which is a "proper" json return, and can be parsed correctly. Adding | jq . after the curl call correctly parses the output:

$ curl -s localhost:8000/test2?gear=4 | jq .
[
{
"mpg": 21,
"cyl": 6,
"disp": 160,
"hp": 110,
"drat": 3.9,
"wt": 2.62,
"qsec": 16.46,
"vs": 0,
"am": 1,
"gear": 4,
"carb": 4
},
...
]

Notes:

  1. I should note that this is not unique to dplyr, and there should be no blame assigned there. The same behavior can be seen with base::with and base::within. Compare the two:

    func <- function(carb, gear) { browser(); 1; }
    func(1, 3)
    # Called from: func(1, 3)
    debug at #1: [1] 1
    c. <- carb
    g. <- gear
    with(mtcars, { gear == as.numeric(gear) & carb == as.numeric(carb); })
    # [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
    # [16] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
    # [31] TRUE TRUE
    with(mtcars, { gear == as.numeric(g.) & carb == as.numeric(c.); })
    # [1] FALSE FALSE FALSE TRUE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
    # [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
    # [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE


Related Topics



Leave a reply



Submit