【问题标题】:filter_ with string argumentfilter_ 带字符串参数
【发布时间】:2014-10-29 18:27:24
【问题描述】:

这很有效(在 Shiny 中非常好用):

filter_(mtcars, "mpg > 24")

还有这个:

filter_(mtcars, "mpg > 24", "disp > 75")

有没有办法让它也能正常工作?

filter_(mtcars, "mpg > 24, disp > 75")

这是一种替代方法

filter_(mtcars, "mpg > 24 & disp > 75")

编辑 1

这可行,但有更好的方法吗?

filter_(mtcars,unlist(strsplit("mpg > 24, disp > 75", ",")))

编辑 2

之前的编辑可能无法按预期工作。相当于如下:

filter_(mtcars,c("mpg > 24", "disp > 75"))

忽略第二个条件

  mpg cyl  disp  hp drat   wt qsec vs am gear carb
  1 24.4   4 146.7  62 3.69 3.19 20.0  1  0    4    2
  2 32.4   4  78.7  66 4.08 2.20 19.5  1  1    4    1
  3 30.4   4  75.7  52 4.93 1.61 18.5  1  1    4    2
  4 33.9   4  71.1  65 4.22 1.83 19.9  1  1    4    1
  5 27.3   4  79.0  66 4.08 1.94 18.9  1  1    4    1
  6 26.0   4 120.3  91 4.43 2.14 16.7  0  1    5    2
  7 30.4   4  95.1 113 3.77 1.51 16.9  1  1    5    2

【问题讨论】:

  • 替代方案 (&) 恕我直言更好。也更通用,因为您可以使用其他运算符,例如 |
  • filter_(mtcars, c("mpg > 24", "disp > 75")) 怎么样?您面临的具体问题是什么?
  • 你可能是对的@flodel,但我想选择输入是“标准”dplyr 表示法
  • 试试do.call(filter_, c(list(mtcars),unlist(strsplit("mpg > 24, disp > 75", ","))))。我无法测试,因为您没有提供可重现的示例。
  • FWIW 尝试filter_(mtcars, .dots = c("mpg > 24", "disp > 75"))

标签: r shiny dplyr


【解决方案1】:

所以我在这里的假设是您从textInput 获取过滤参数,因此它们以文本形式出现。这是一种有效的方法:

library(dplyr)
Args<-c("mpg>24, disp>75")
eval( parse( text=paste("filter(mtcars,",Args,")")    ))

   mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
2 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
3 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
4 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
5 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
6 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2

所以在这种情况下Args 是来自用户的输入。我使用 paste 将一个完整的 filter 函数组合成一个文本字符串。最后,eval(parse (..)) 位只是评估字符串,就好像它是一个普通函数一样。请注意,这里使用filter 而不是filter_

此答案基于此问题的公认答案:

Use character string as function argument

【讨论】:

  • 感谢约翰的意见。我之前已经将这种方法与“子集”一起使用。工作正常,但我正试图减少我对 eval-parse 的摄入量。当在服务器上运行时,我假设 hadley 或 flodel 方法的安全风险比较低
【解决方案2】:

为了完整起见,我将放弃使用gsub 将字符串中的逗号替换为和号的(可能是微不足道的)解决方案:

filter_(mtcars, gsub(',', '&', "mpg > 24, disp > 75"))

   mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
2 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
3 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
4 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
5 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
6 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2

如果您将该条件作为纯表达式输入filter,这将产生与您期望的相同的输出,如果没有逗号或如果用户选择使用&amp;,则可以正常工作,并且不引入涉及在任意表达式上使用eval 的潜在风险。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-07
    • 2019-11-23
    • 1970-01-01
    • 2021-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多