Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
121 views
in Technique[技术] by (71.8m points)

r - How to create a string that can be used as LHS and assigned a value to?

I feel stupid for asking such a simple question, but I am hitting my head in the wall.
Why does the paste0() create a string that cannot be not interpreted as name for an empty object ? Is there a different way of create the LHS that would be better?

As input I have a dataframe. As an output I want to have a new filtered dataframe. This works fine as long as I manually type all the code. However, I am trying to reduce repetition, and therefore I want to create a function that does the same thing, but then it is not working anymore.

library(magrittr)

df <- data.frame(
    var_a = round(runif(20), digits = 1),
    var_b = sample(letters, 20)
  )


### Find duplicates

df$duplicate_num <-  duplicated(df$var_a)
df$duplicate_txt <-  duplicated(df$var_b)
df                      # a check


### Create two lists of duplicates

list_of_duplicate_num <-
  df %>%
  filter(duplicate_num)
list_of_duplicate_num      # a check

list_of_duplicate_txt <-
  df %>%
  filter(duplicate_txt)
list_of_duplicate_txt    # a check '

So far everything works as expected.

I would like to simplify the code and make this to a function that takes the arguments "num" or "txt". But I am having problems with creating the LHS. The below should, in my mind, do the same as the code above.

 paste0("list_of_duplicate_", "num") <-
  df %>%
  filter(duplicate_num) 

I do get an error message:

Error in paste0("list_of_duplicate_", "num") <- df %>% 
filter(duplicate_num) : 
target of assignment expands to non-language object

My goal is to create a function with something like this:

make_list_of_duplicates <- function(criteria = "num") {
  paste0("list_of_duplicate_", criteria) <-
    df %>%
    filter(paste0("duplicate_", criteria))
  paste0("list_of_duplicate_", criteria)    # a check
}

### Create two lists of duplicates

make_list_of_duplicates("num")
make_list_of_duplicates("txt")

and then continue with some joins etc.

I have been looking to tidy evaluation, assignments, rlang::enexpr(), base::substitute(), get(), mget() and many other things, but after two day of reading and trial and error, I am convinced that there must be a an other direction to look at that I am not seeing.

I am running MS Open R 4.0.2.

I am grateful for any suggestions.

Sincerely, Eero

question from:https://stackoverflow.com/questions/65887307/how-to-create-a-string-that-can-be-used-as-lhs-and-assigned-a-value-to

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I found the solution to my question, when I understood that it was a case of indirection. Because I was on a wrong track, I created lots of complications and made it more difficult than necessary. Thanks to @r2evans who pointed me in the right direction. I have in the mean time decided that I will use loops, instead of functions, but here is the working function:

## Example of using paste inside a function to refer to an object.
library(magrittr)
library(dplyr)

 
df <- data.frame(
    var_a = round(runif(20), digits = 1),
    var_b = sample(letters, 20)
  )


# Find duplicates

df$duplicate_num <-  duplicated(df$var_a)
df$duplicate_txt <-  duplicated(df$var_b)

# SEE https://dplyr.tidyverse.org/articles/programming.html#indirection-2

make_list_of_duplicates_f2 <- function(criteria = "num") {
  df %>%
    filter(.data[[paste0("duplicate_", {{criteria}})]])
}

# Create two lists of duplicates

list_of_duplicates_f2_num <-
    make_list_of_duplicates_f2("num")
list_of_duplicates_f2_txt <-
    make_list_of_duplicates_f2("txt")

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...