2016-06-20 10 views
4

ich einen Datenrahmen haben, die wie etwas aussieht:‚richtige‘ Art und Weise zu tun, reihenweise Ersatz

dataDemo <- data.frame(POS = 1:4 , REF = c("A" , "T" , "G" , "C") , 
    ind1 = c("A" , "." , "G" , "C") , ind2 = c("A" , "C" , "C" , "."), 
                stringsAsFactors=FALSE) 

dataDemo 

    POS REF ind1 ind2 
1 1 A A A 
2 2 T . C 
3 3 G G C 
4 4 C C . 

und ich möchte alle ersetzen s mit dem REF Wert für die Zeile „“ . Hier ist, wie ich es tat:

for(i in seq_along(dataDemo$REF)){ 
    dataDemo[i , ][dataDemo[i , ] == '.'] <- dataDemo$REF[i] 
} 

Ich mag gerne wissen, ob es ein ‚richtiger‘ oder idiomatischer Weg, dies in R. zu tun, im Allgemeinen zu verwenden, ich versuche * anwenden, wann immer möglich, und dies scheint wie etwas, das könnte leicht an diesen Ansatz angepasst und lesbarer (und schneller) gemacht werden, aber trotz der Tatsache, dass ich ein wenig Zeit damit verbracht habe, habe ich keine großen Fortschritte gemacht.

Antwort

7

Hier ist eine andere base R Alternative, wo wir die Zeilennummern der "." Ereignisse verwenden, um sie durch die entsprechenden REF Werte zu ersetzen.

# Get row numbers 
rownrs <- which(dataDemo==".", arr.ind = TRUE)[,1] 

# Replace values 
dataDemo[dataDemo=="."] <- dataDemo$REF[rownrs] 

# Result 
dataDemo 
# POS REF ind1 ind2 
#1 1 A A A 
#2 2 T T C 
#3 3 G G C 
#4 4 C C C 
+0

Perfekt einfach. Das ist, was passiert, wenn ich gehe und versuche, C. zu lernen. – mnosefish

4

Hier ist eine Option set von data.table, die schnell sein sollte.

library(data.table) 
setDT(dataDemo) 
nm1 <- paste0("ind", 1:2) 
for(j in nm1){ 
    i1 <- dataDemo[[j]]=="." 
    set(dataDemo, i = which(i1), j=j, value = dataDemo$REF[i1]) 
} 

dataDemo 
# POS REF ind1 ind2 
#1: 1 A A A 
#2: 2 T T C 
#3: 3 G G C 
#4: 4 C C C 

EDIT: Basierend auf @ alexis_laz Kommentare


Oder mit dplyr

library(dplyr) 
dataDemo %>% 
    mutate_each(funs(ifelse(.==".", REF,.)), ind1:ind2) 
# POS REF ind1 ind2 
#1 1 A A A 
#2 2 T T C 
#3 3 G G C 
#4 4 C C C 

Oder können wir base R Methoden verwenden, um dies in einer einzigen Zeile zu tun.

dataDemo[nm1] <- lapply(dataDemo[nm1], function(x) ifelse(x==".", dataDemo$REF, x)) 
+1

Speichern, in jeder Iteration ein 'i = dataDemo [[j]] == ""', um zu verhindern es zweimal Berechnung, sollte es noch mehr effizient. –

8

In dplyr,

library(dplyr) 

dataDemo %>% mutate_each(funs(ifelse(. == '.', REF, as.character(.))), -POS) 
# POS REF ind1 ind2 
# 1 1 A A A 
# 2 2 T T C 
# 3 3 G G C 
# 4 4 C C C 
+0

Ich muss etwas Zeit investieren, um plyr und dplyr besser zu nutzen. – mnosefish

+0

'plyr' ist etwas abgelöst von' dplyr', so dass Sie wahrscheinlich nur das letztere lernen müssen. Es wird wahrscheinlich auch nicht zu lange dauern; es ist ziemlich einfach. – alistaire

+0

@akrun Ziemlich viel, aber es wurde ursprünglich veröffentlicht, bevor Sie 'dplyr' in den Schnitt eingefügt haben. Auch Ihr wird Probleme haben, wenn 'stringsAsFactors = TRUE' ist. – alistaire

Verwandte Themen