在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"