2017-04-05 4 views
1

Ich muss die 0 durch 1 ersetzen, aber nur dort, wo die Werte die folgenden Bedingungen erfüllen; "1 0 1" oder "0 1" (wenn am Anfang) oder "1 0" (wenn am Ende). Gegeben das Beispiel Datenrahmen:Ersetzen Sie die Zeilenwerte im Datenframe, die spezielle Bedingungen erfüllen

df <- data.frame(a = c(1,0,1,0,1,1,1,0,1,1,1), 
       b = c(1,1,1,0,1,1,1,0,1,1,1), 
       c = c(1,0,1,1,1,0,1,0,1,1,1), 
       d = c(1,1,1,0,1,1,1,1,1,1,1), 
       e = c(1,0,1,0,1,1,1,1,1,1,1), 
       f = c(1,1,1,1,1,1,1,1,1,0,1)) 
df 

Es brauchen würde es zurück:

df.result <- data.frame(a = c(1,1,1,0,1,1,1,0,1,1,1), 
         b = c(1,1,1,0,1,1,1,0,1,1,1), 
         c = c(1,1,1,1,1,1,1,0,1,1,1), 
         d = c(1,1,1,0,1,1,1,1,1,1,1), 
         e = c(1,1,1,0,1,1,1,1,1,1,1), 
         f = c(1,1,1,1,1,1,1,1,1,1,1)) 
df.result 

Beachten Sie, dass die entsprechende 0'en hat 1 s geändert. Im Wesentlichen versuche ich, alle Nullen zu ersetzen, die einzeln nacheinander auftreten.

Irgendeine Idee, wie man das in R erreicht?

Vielen Dank im Voraus.

+0

'rollapply()' aus dem Paket 'zoo' für jede Zeile nützlich sein könnte . ... oder 'rle()' von 'Basis' – jogo

Antwort

1

Hier ist eine Lösung mit rle():

foo <- function(x) { 
    r <- rle(x) 
    r$values[r$values==0 & r$lengths==1] <- 1 
    inverse.rle(r) 
} 
foo(c(0,1,0,0,1,0,1)) # testing the working horse: 
# [1] 1 1 0 0 1 1 1 

nun diese Funktion auf jeder Zeile anzuwenden, und das Ergebnis die gewünschte Form geben. apply() nötigt ihr erstes Argument an eine Matrix:

t(apply(df, 1, foo)) 
# > t(apply(df,1,foo)) 
#  [,1] [,2] [,3] [,4] [,5] [,6] 
# [1,] 1 1 1 1 1 1 
# [2,] 1 1 1 1 1 1 
# [3,] 1 1 1 1 1 1 
# [4,] 0 0 1 0 0 1 
# [5,] 1 1 1 1 1 1 
# [6,] 1 1 1 1 1 1 
# [7,] 1 1 1 1 1 1 
# [8,] 0 0 0 1 1 1 
# [9,] 1 1 1 1 1 1 
# [10,] 1 1 1 1 1 1 
# [11,] 1 1 1 1 1 1 

Wenn Sie einen Datenrahmen als Ergebnis wollen Sie tun können:

df.result <- df 
df.result[,] <- t(apply(df,1,foo)) 
+0

Danke! Was für eine schöne Lösung. – Ross

Verwandte Themen