2016-11-12 1 views
1

Ich habe einen Legacy-R-Code geerbt, mit dem einige Werte in einer Spalte basierend auf einem Wert in einer anderen Spalte in derselben Zeile umgeschrieben wurden dass irrtümlich dachte, ein boolescher Wert sein, wenn in Wirklichkeit diese Werte waren tatsächlich (Strings umgewandelt werden) Faktoren, etwa so:R: Zufälliges Subsetting eines Datenrahmens unter Verwendung einer Faktorspalte, als wäre es logisch

df <- data.frame(value = c(1, 2, 3, 4, 5, 6), 
       reversed = c("true", "false", 
           "true", "true", 
           "false", "false")) 

str(df) 
#> 'data.frame': 6 obs. of 2 variables: 
#> $ value : num 1 2 3 4 5 6 
#> $ reversed: Factor w/ 2 levels "false","true": 2 1 2 2 1 1 

df$recoded_value <- df$value 
df$recoded_value[df$reversed] <- 7 - df$recoded_value[df$reversed] 

Wenn Sie die Ergebnisse überprüfen, dies erzeugt unbeabsichtigte Ergebnisse. df[2, "recoded_value"] ist 5, aber die Absicht ist es für 2 zu sein. Darüber hinaus ist df[3, "recoded_value"] 3, aber die Absicht ist es zu sein 4.

Ich würde gerne verstehen, was hier vor sich geht. Meine erste Hypothese war, dass R einen Faktor als TRUE und den anderen als FALSE behandelt. Aber das ist natürlich nicht der Fall, weil identische Faktorstufen sind nicht identisch behandelt werden:

df[c(1,3), ] 
#> value reversed recoded_value 
#> 1  1  true    6 
#> 3  3  true    3 

df[c(2,5), ] 
#> value reversed recoded_value 
#> 2  2 false    5 
#> 5  5 false    5 

Was ist hier los?

Um zu verdeutlichen: Ich bin nicht an Lösungen für das Problem interessiert. Ich weiß, wie man den Code repariert, um die beabsichtigten Ergebnisse zu erzielen. Ich würde gerne verstehen:

  1. Warum funktioniert dieser Code überhaupt? Wie können Sie eine Teilmenge auf der Grundlage einer Faktorspalte erstellen? Was macht `[`, um dies zu ermöglichen?
  2. Warum werden die Dinge, die den gleichen Wert haben (, d. H., gleiche Ebene eines Faktors) unterschiedlich behandelt?

Antwort

1

Wie es in der Post erwähnt wird, ist reversed ein factor und kein logical Vektor. In R sind TRUE/FALSE Werte die logische, so konvertieren, um logical Vektor

df$reversed <- df$reversed=="true" 

Bezüglich warum wir unerwarteten Ausgang haben (aus dem Code des OP),

df$reversed 
#[1] true false true true false false 
#Levels: false true 

der levels in alphabetischer Reihenfolge sind und der Speichermodus von factor ist integer dh

as.integer(df$reversed) 
#[1] 2 1 2 2 1 1 
So

wenn wir Teilmenge der ‚recoded_value‘ mit dem ‚umgekehrt‘, wird es auf dem numerischen Index Teilmenge basiert

df$recoded_value[df$reversed] 
#[1] 2 1 2 2 1 1 

dh der erste Wert in der Ausgabe die zweite Beobachtung von ‚recoded_value‘ ist und die zweiten ersten Beobachtung und so weiter, statt, wenn wir den richtigen logischen Index

df$recoded_value[df$reversed=="true"] 
#[1] 1 3 4 

Lassen Sie uns überprüfen, wie dies mit der veränderten verhalten ‚umgekehrt‘

df$reversed <- df$reversed=="true" 
df$recoded_value[df$reversed] <- 7 - df$recoded_value[df$reversed] 
df[c(1,3), ] 
# value reversed recoded_value 
#1  1  TRUE    6 
#3  3  TRUE    4 
df[c(2,5),] 
# value reversed recoded_value 
#2  2 FALSE    2 
#5  5 FALSE    5 
+1

Danke für die Antwort! Nicht sicher warum ich das vorher nicht bemerkt habe. Ich denke, ich wählte schlechte Zahlen, wenn ich das minimale Beispiel konstruierte; Ich hätte keine Werte auswählen sollen, die mit der Zeilennummer identisch sind. ': -p' Jedenfalls, danke. +1 –

Verwandte Themen