首页 > 解决方案 > 如何创建一个可用作 LHS 并为其赋值的字符串?

问题描述

问这么简单的问题我觉得很愚蠢,但我的头撞到了墙上。
为什么 paste0() 会创建一个不能解释为空对象名称的字符串?有没有更好的创建 LHS 的不同方法?

作为输入,我有一个数据框。作为输出,我想要一个新的过滤数据框。只要我手动输入所有代码,它就可以正常工作。但是,我试图减少重复,因此我想创建一个做同样事情的函数,但是它不再工作了。

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 '

到目前为止,一切都按预期工作。

我想简化代码并将其变成一个接受参数“num”或“txt”的函数。但是我在创建 LHS 时遇到了问题。在我看来,下面的代码应该和上面的代码一样。

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

我确实收到一条错误消息:

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

我的目标是创建一个类似这样的函数:

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.

我一直在寻找整洁的评估、作业、rlang::enexpr()、base::substitute()、get()、mget() 和许多其他东西,但是经过两天的阅读和反复试验,我确信必须有另一个我看不到的方向。

我正在运行 MS Open R 4.0.2。

我很感激任何建议。

真诚的,埃罗

标签: robject

解决方案


当我了解到这是一个间接情况时,我找到了问题的解决方案。因为我走错了路,所以我制造了很多复杂的事情,并且变得比必要的更困难。感谢@r2evans,他为我指明了正确的方向。与此同时,我决定使用循环而不是函数,但这里是工作函数:

## 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")

推荐阅读