如何通过将字符串作为用户定义函数中的列名传递为列名来过滤?

发布于 2025-01-21 12:51:49 字数 903 浏览 4 评论 0原文

我正在编写一个函数,其中用户指定要过滤的列以及所需的截止值。在此示例中,我想滤除2下的任何预测分数。这是一个示例数据集:

library(dplyr)

test <- tibble(name = c("Corey", "Justin", "Sibley", "Kate"),
               pretest_score = c(1:4),
               posttest_score = c(5:8),
               final_score = c(9:12))


filter_function <- function(data, test_type = c(pretest, posttest, final), value) {
  
  test_character <- deparse(substitute(test_type))
  test_score <- paste0(test_character, "_score")
  
  data %>%
    filter({{test_score}} > value)
  
}

filter_function(test, test_type = pretest, value = 2)

我也尝试了!test_score,test_score(周围什么都没有),以及rlang ,无济于事。

注意:我知道在 this 示例中,我只能将Pretest_score,tostTest_score等指定为测试类型,但是在我的真实数据集中,我对这些测试有许多维度,用户可以确定这些测试的临界值( Pretest_score,Pretest_date,Pretest_location等),因此,我必须在功能本身中与后缀(此处,_score)合并列前缀。

感谢您的任何帮助!

I'm writing a function where the user specifies the column they want to filter and what cutoff value they want. In this example, I want to filter out any pretest scores under 2. Here's a sample dataset:

library(dplyr)

test <- tibble(name = c("Corey", "Justin", "Sibley", "Kate"),
               pretest_score = c(1:4),
               posttest_score = c(5:8),
               final_score = c(9:12))


filter_function <- function(data, test_type = c(pretest, posttest, final), value) {
  
  test_character <- deparse(substitute(test_type))
  test_score <- paste0(test_character, "_score")
  
  data %>%
    filter({{test_score}} > value)
  
}

filter_function(test, test_type = pretest, value = 2)

I've also tried !!test_score, test_score (with nothing around it), and ensym(test_score) from rlang, all to no avail.

Note: I know that in this example, I could just specify pretest_score, posttest_score, etc as the test type, but in my real dataset, I have many dimensions for these tests that users can determine cutoffs for (pretest_score, pretest_date, pretest_location, etc.), so it's important that I merge the column prefix with the suffix (here, _score) within the function itself.

Thank you for any help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

天涯离梦残月幽梦 2025-01-28 12:51:49

将字符转换为sym bol并使用!!进行评估

filter_function <- function(data, test_type = c(pretest, posttest, 
      final), value) {
  
  test_character <- deparse(substitute(test_type))
  test_score <- paste0(test_character, "_score")
  
  data %>%
    filter(!! rlang::sym(test_score) > value)
  
}

- 测试

> filter_function(test, test_type = pretest, value = 2)
# A tibble: 2 × 4
  name   pretest_score posttest_score final_score
  <chr>          <int>          <int>       <int>
1 Sibley             3              7          11
2 Kate               4              8          12

Convert the character to symbol and evaluate with !!

filter_function <- function(data, test_type = c(pretest, posttest, 
      final), value) {
  
  test_character <- deparse(substitute(test_type))
  test_score <- paste0(test_character, "_score")
  
  data %>%
    filter(!! rlang::sym(test_score) > value)
  
}

-testing

> filter_function(test, test_type = pretest, value = 2)
# A tibble: 2 × 4
  name   pretest_score posttest_score final_score
  <chr>          <int>          <int>       <int>
1 Sibley             3              7          11
2 Kate               4              8          12
一身仙ぐ女味 2025-01-28 12:51:49

几点:

  • 通常,当R中使用一组选项时,一个使用字符向量而不是未评估的表达式。 r专门为此目的提供match.arg。这还实现了第一个选项的默认值,因此,如果我们使用match.arg调用函数可以省略type_test =“ Prepest”,因为这是默认值。 /p>

  • 。[[test_score]]可以用来指定指示的列

因此我们

filter_function <- function(data, test_type = c("pretest", "posttest", "final"), 
  value) {

  test_type <- match.arg(test_type)
  test_score <- paste0(test_type, "_score")
  
  data %>%
    filter(.[[test_score]] > value)
  
}

filter_function(test, test_type = "pretest", value = 2)
# A tibble: 2 x 4
  name   pretest_score posttest_score final_score
  <chr>          <int>          <int>       <int>
1 Sibley             3              7          11
2 Kate               4              8          12

# pretest is the default
filter_function(test, value = 2)
# A tibble: 2 x 4
  name   pretest_score posttest_score final_score
  <chr>          <int>          <int>       <int>
1 Sibley             3              7          11
2 Kate               4              8          12

还指出我们可以像这样指定函数。由于match.arg,用户仍然可以指定“预测”。实际上,他们甚至可以指定“ pre”或“ post”。

filter_function2 <- function(data, 
    test_type = c("pretest_score", "posttest_score", "final_score"), 
    value) {

  test_type <- match.arg(test_type)
  
  data %>%
    filter(.[[test_type]] > value)
  
}

filter_function2(test, test_type = "pretest", value = 2)

基本r

这也可以在没有任何类似包的情况下完成:

filter_function3 <- function(data, test_type = c("pretest", "posttest", "final"), 
  value) {

  test_type <- match.arg(test_type)
  test_score <- paste0(test_type, "_score")
  
  data[data[[test_score]] > value, ]

}

filter_function3(test, test_type = "pretest", value = 2)

A few points:

  • normally when a set of options are used in R one uses a character vector, not an unevaluated expression. R specifically provides match.arg for this purpose. This also implements a default of the first option so if we use match.arg the call invoking the function could have omitted type_test = "pretest" as that is the default.

  • .[[test_score]] can be used to specify the indicated column

Thus we have

filter_function <- function(data, test_type = c("pretest", "posttest", "final"), 
  value) {

  test_type <- match.arg(test_type)
  test_score <- paste0(test_type, "_score")
  
  data %>%
    filter(.[[test_score]] > value)
  
}

filter_function(test, test_type = "pretest", value = 2)
# A tibble: 2 x 4
  name   pretest_score posttest_score final_score
  <chr>          <int>          <int>       <int>
1 Sibley             3              7          11
2 Kate               4              8          12

# pretest is the default
filter_function(test, value = 2)
# A tibble: 2 x 4
  name   pretest_score posttest_score final_score
  <chr>          <int>          <int>       <int>
1 Sibley             3              7          11
2 Kate               4              8          12

Also note that we could specify the function like this. The user can still specify "pretest" since match.arg will match the leading substring. In fact they could even specify "pre" or "post".

filter_function2 <- function(data, 
    test_type = c("pretest_score", "posttest_score", "final_score"), 
    value) {

  test_type <- match.arg(test_type)
  
  data %>%
    filter(.[[test_type]] > value)
  
}

filter_function2(test, test_type = "pretest", value = 2)

Base R

This could also be done without any packages like this:

filter_function3 <- function(data, test_type = c("pretest", "posttest", "final"), 
  value) {

  test_type <- match.arg(test_type)
  test_score <- paste0(test_type, "_score")
  
  data[data[[test_score]] > value, ]

}

filter_function3(test, test_type = "pretest", value = 2)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文