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

时间:2017-11-15 10:45:26

标签: 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=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 "

如果有人能帮我解决这个问题,我将不胜感激。

2 个答案:

答案 0 :(得分:2)

这里的难点来自于使用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]"
)

而不是那样,我将采取另一种方式,因为在r的每个元素中,您只需要识别列的名称。例如,在第一种情况下,您只需要AB

library(purrr)
library(glue)
library(rlang)
names <- c("A", "B")
DF <- data.frame(
  A = c(11, 11, 2, 3),
  B = c(22, 22, 30, 30),
  C = c(88, 47, 21, 21)
)

map( names, ~{
  glue( "{name} == {values}", name = ., values = DF[[.]] )
})
#> [[1]]
#> A == 11
#> A == 11
#> A == 2
#> A == 3
#> 
#> [[2]]
#> B == 22
#> B == 22
#> B == 30
#> B == 30

然后你可以reduce只获得数据框每行一个字符串:

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"

将它全部包装到一个使用整齐的eval来获取名称开头的函数中:

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

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

}

这样您就可以通过拨打tests 4次获得结果:

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"

答案 1 :(得分:0)

这是你输出的产品吗?

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
...