2017-11-15 7 views
2

Beispieldaten:Schleife innerhalb Zeichenfolge in r Ausgabeausdrücke mit vektorisiert Werten

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

ausgeführtem Code:

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

Mein Ziel die gleiche Ausgabe mit den spezifischen Werten A [i] zu erhalten war , B [i] und C [i] von DF, das heißt, würde die endgültige Ausgabe der folgenden sein:

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

ich wäre dankbar, wenn jemand hel könnte p mich mit dieser Angelegenheit.

Antwort

2

Die Schwierigkeit kommt von der Art und Weise das Problem mit dem r Vektor angegeben ist, und es wäre möglich, Mailand Antwort zu ändern, besser das erwartete Ergebnis entsprechen.

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]" 
) 

Statt dessen werde ich einen anderen Weg nehmen, da Sie nur in jedem Element von r, müssen die Namen der Spalten zu identifizieren. Im ersten Fall benötigen Sie beispielsweise nur A und B.

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 

können Sie dann reduce es nur pro Zeile Ihres Datenrahmen eine Zeichenfolge zu erhalten:

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" 

alles bis in eine Funktion Wrapping, die ordentlich eval verwendet den Namen, um zu beginnen:

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

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

} 

Damit Sie die Ergebnisse durch den Aufruf tests 4 mal bekommen kann:

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" 
+0

Vielen Dank, Romain. Ich habe den Code ausgeführt, aber ich habe "Fehler in as_function (.f, ...): object 'f_name' nicht gefunden". Ich habe etwas falsch gemacht, denke ich. Kannst du mir den Weg zeigen, das zu lösen? – Citizen

+0

Ich hätte wahrscheinlich 'rlang' auch laden sollen. Ich habe gerade 'library (rlang)' hinzugefügt. –

+1

Vielen Dank, Romain. Es funktioniert sehr gut. Nun muss ich darüber nachdenken und daran arbeiten, dies mit einer beliebigen Anzahl von Spalten zu tun, d. H. Für jeden großen Datenrahmen, aber das wäre eine andere potentielle Frage. Ich habe Ihre Antwort als die beste richtige Antwort ausgewählt. Bitte lass es mich wissen, wenn ich etwas anderes machen muss. – Citizen

0

Ist diese Ausgabe, wonach Sie suchen?

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

Oder umgeben Sie vielleicht den Ausdruck mit einem 'mit (DF)', um das riskante 'gsub' zu vermeiden, z. 'output [[j]] [i] <- DF [mit (DF, eval (parse (text = j)))]] –

+0

Guter Vorschlag. Ich habe den Code bearbeitet. –

+0

Vielen Dank. Ich fürchte, meine Frage wurde nicht richtig gestellt, so dass ich es besser erklärt habe. – Citizen

Verwandte Themen