在r中的字符串内循环以输出具有矢量化值的表达式

在r中的字符串内循环以输出具有矢量化值的表达式,r,R,示例数据: > DF A B C 1 11 22 88 2 11 22 47 3 2 30 21 4 3 30 21 > r [1] "A==A[i] & B==B[i] " "A==A[i] & C==C[i] " [3] "B==B[i] & C==C[i] " "A==A[i] & B==B[i] & C==C[i] " 执行代码: > output=li

示例数据:

> DF
   A  B  C
1 11 22 88
2 11 22 47
3  2 30 21
4  3 30 21

> r
[1] "A==A[i] & B==B[i] "           "A==A[i] & C==C[i] "          
[3] "B==B[i] & C==C[i] "           "A==A[i] & B==B[i] & C==C[i] "
执行代码:

> output=list()
> for (j in r){
+   for (i in 1:nrow(DF)){
+    
+     output[[j]][i]=j  
+   }
+ }
> output
$`A==A[i] & B==B[i] `
[1] "A==A[i] & B==B[i] " "A==A[i] & B==B[i] " "A==A[i] & B==B[i] "
[4] "A==A[i] & B==B[i] "

$`A==A[i] & C==C[i] `
[1] "A==A[i] & C==C[i] " "A==A[i] & C==C[i] " "A==A[i] & C==C[i] "
[4] "A==A[i] & C==C[i] "

$`B==B[i] & C==C[i] `
[1] "B==B[i] & C==C[i] " "B==B[i] & C==C[i] " "B==B[i] & C==C[i] "
[4] "B==B[i] & C==C[i] "

$`A==A[i] & B==B[i] & C==C[i] `
[1] "A==A[i] & B==B[i] & C==C[i] " "A==A[i] & B==B[i] & C==C[i] "
[3] "A==A[i] & B==B[i] & C==C[i] " "A==A[i] & B==B[i] & C==C[i] "

> output=purrr::flatten_chr(output)
> output
 [1] "A==A[i] & B==B[i] "           "A==A[i] & B==B[i] "          
 [3] "A==A[i] & B==B[i] "           "A==A[i] & B==B[i] "          
 [5] "A==A[i] & C==C[i] "           "A==A[i] & C==C[i] "          
 [7] "A==A[i] & C==C[i] "           "A==A[i] & C==C[i] "          
 [9] "B==B[i] & C==C[i] "           "B==B[i] & C==C[i] "          
[11] "B==B[i] & C==C[i] "           "B==B[i] & C==C[i] "          
[13] "A==A[i] & B==B[i] & C==C[i] " "A==A[i] & B==B[i] & C==C[i] "
[15] "A==A[i] & B==B[i] & C==C[i] " "A==A[i] & B==B[i] & C==C[i] "
我的目标是从DF获得具有特定值A[i]、B[i]和C[i]的相同输出,即,最终输出如下:

> output
[1] "A==11 & B==22 "            "A==11 & B==22 "          
[3] "A==2 & B==30 "             "A==3 & B==30 "          
[5] "A==11 & C==88 "            "A==11 & C==47 "          
[7] "A==2 & C==21 "             "A==3 & C==21 "          
[9] "B==22 & C==88 "            "B==22 & C==47 "          
[11] "B==30 & C==21 "           "B==30 & C==21 "          
[13] "A==11 & B==22 & C==88 "   "A==11 & B==22 & C==47 "
[15] "A==2 & B==30 & C==21 "    "A==3 & B==30 & C==21 "

如果有人能帮我解决这件事,我将不胜感激。

这是您想要的输出吗

DF <- data.frame(A = c(11, 11, 2, 3),
                 B = c(22, 22, 30, 30),
                 C = c(88, 47, 21, 21))

r <- c("A==A[i] & B==B[i]", "A==A[i] & C==C[i]",
       "B==B[i] & C==C[i]", "A==A[i] & B==B[i] & C==C[i]")

output=list()
for (j in r){
  for (i in 1:nrow(DF))
    output[[j]][[i]] <- DF[with(DF, eval(parse(text = j))), ]
}

output

$`A==A[i] & B==B[i]`
$`A==A[i] & B==B[i]`[[1]]
   A  B  C
1 11 22 88
2 11 22 47

$`A==A[i] & B==B[i]`[[2]]
   A  B  C
1 11 22 88
2 11 22 47

$`A==A[i] & B==B[i]`[[3]]
  A  B  C
3 2 30 21

$`A==A[i] & B==B[i]`[[4]]
  A  B  C
4 3 30 21


$`A==A[i] & C==C[i]`
$`A==A[i] & C==C[i]`[[1]]
   A  B  C
1 11 22 88
...

DF这里的困难来自于用
r
向量指定问题的方式,可以修改米兰的答案以更好地匹配预期结果

r <- c(
  "A==A[i] & B==B[i]", 
  "A==A[i] & C==C[i]",
  "B==B[i] & C==C[i]", 
  "A==A[i] & B==B[i] & C==C[i]"
)
然后,您可以
减少
它,使数据帧的每行仅获得一个字符串:

map( names, ~{
  glue( "{name} == {values}", name = ., values = DF[[.]] )
}) %>% 
  reduce( paste, sep = " & ")
#> [1] "A == 11 & B == 22" "A == 11 & B == 22" "A == 2 & B == 30" 
#> [4] "A == 3 & B == 30"
将所有内容包装到一个函数中,该函数使用tidy eval来获取开头的名称:

tests <- function(data, ...){
  names <- map_chr(quos(...), f_name)

  map( names, ~{
    glue( "{name} == {values}", name = ., values = data[[.]] )
  }) %>% 
    reduce(paste, sep = " & " )

}

或者在表达式周围加一个
和(DF)
,以避免危险的
gsub
,例如
输出[[j]][i]非常感谢。恐怕我的问题问得不对,所以我解释得更好。非常感谢你,罗曼。我已经运行了代码,但是我得到了“as_函数(.f,…)中的错误:找不到对象'f_name'。我想我做错了什么。你能告诉我解决这个问题的方法吗?我可能也应该加载
rlang
。我刚刚添加了
库(rlang)
。非常感谢你,罗曼。它工作得很好。现在,我必须考虑并致力于使用任意数量的列来实现这一点,例如,对于任何大数据帧输入,但这将是另一个潜在的问题。我选择了你的答案作为最正确的答案。如果我有别的事,请告诉我。
tests <- function(data, ...){
  names <- map_chr(quos(...), f_name)

  map( names, ~{
    glue( "{name} == {values}", name = ., values = data[[.]] )
  }) %>% 
    reduce(paste, sep = " & " )

}
c(
  tests( DF, A, B), 
  tests( DF, A, C), 
  tests( DF, B, C), 
  tests( DF, A, B, C)
)
#>  [1] "A == 11 & B == 22"           "A == 11 & B == 22"          
#>  [3] "A == 2 & B == 30"            "A == 3 & B == 30"           
#>  [5] "A == 11 & C == 88"           "A == 11 & C == 47"          
#>  [7] "A == 2 & C == 21"            "A == 3 & C == 21"           
#>  [9] "B == 22 & C == 88"           "B == 22 & C == 47"          
#> [11] "B == 30 & C == 21"           "B == 30 & C == 21"          
#> [13] "A == 11 & B == 22 & C == 88" "A == 11 & B == 22 & C == 47"
#> [15] "A == 2 & B == 30 & C == 21"  "A == 3 & B == 30 & C == 21"