R和tidyverse有一些非常强大但同样神秘的方法,可以将字符串转换为可操作的表达式。我觉得需要成为一名专家才能真正了解如何使用它们。
注意:从这个问题的不同这一个中,我特别问的矢量(也就是多个)过滤条件。我演示了单个过滤器的解决方案,当我尝试将其扩展到多个过滤器的多种方式时,该解决方案失败了。
我想按照以下方式做一些事情:
df = data.frame(A=1:10, B=1:10)
df %>% filter(A<3, B<5)
但是如果过滤器包含在字符串(例如)"A<3, B<5"
或字符向量(例如)中c("A<3", "B<5")
。
我可以
df %>% filter(eval(str2expression("A<3")))
# A B
# 1 1 1
# 2 2 2
但这不起作用:
df %>% filter(eval(str2expression("A<3, B<5")))
Error in str2expression("A<3, B<5") : <text>:1:4: unexpected ','
1: A<3,
^
这些也不起作用:
> df %>% filter(!!c(str2expression("A<3"), str2expression("B<5")))
Error: Argument 2 filter condition does not evaluate to a logical vector
> df %>% filter(!!!c(str2expression("A<3"), str2expression("B<5")))
Error: Can't splice an object of type `expression` because it is not a vector
Run `rlang::last_error()` to see where the error occurred.
str2expression
由于某种原因而评估表达式的向量仅适用于最后一个表达式:
> df %>% filter(eval(c(str2expression("A<3"), str2expression("B<5"))))
# A B
# 1 1 1
# 2 2 2
# 3 3 3
# 4 4 4
使用评估表达式的向量完全失败:
> df %>% filter(!!!c(eval(str2expression("A<3")), eval(str2expression("B<5"))))
Error in eval(str2expression("A<3")) : object 'A' not found
我可以:
> df %>% filter(!!!c(expr(A<3), expr(B<5)))
# A B
# 1 1 1
# 2 2 2
这告诉我,expr(A<3)
这与str2expression("A<3")
但这不是从字符串开始的。
该怎么办?
从@Ronak Shah的答案中吸取教训,显然,在dplyr中,我可以使用多个条件,并使用一个&
in过滤器而不是逗号。我完全不理解这一点-与和逻辑上是不一样的:
> df %>% filter(A<3 & B<5)
A B
1 1 1
2 2 2
> df %>% filter(A<3 && B<5)
A B
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8
9 9 9
10 10 10
但是,以下方法确实有效:
> df %>% filter(eval(str2expression("A<3 & B<5")))
A B
1 1 1
2 2 2
> df %>% filter(eval(str2expression("A<6 & B<5")))
A B
1 1 1
2 2 2
3 3 3
4 4 4
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句