2016-05-30 26 views
1

Ich habe folgendes df:bedingte Berechnung: Länge bestimmter Zeile, wenn Zeile unten ist nicht NA-Wert

  X7 X8 X9 X10 X11 X12 X13 X14 
1   1 1 <NA> 1 1 1 1 <NA>  
2   1 1 1 1 1 1 <NA> <NA> 
3   1 1 1 1 1 <NA> <NA> <NA> 

Edit: diese verwenden:

df <- data.frame(X7=c(1L,1L,1L),X8=c(1L,1L,1L),X9=factor(c(NA,'1','1')),X10=c(1L,1L,1L),X11=c(1L,1L,1L),X12=factor(c('1','1',NA)),X13=factor(c('1',NA,NA)),X14=factor(c(NA,NA,NA))); 

Ich möchte die Länge berechnen der Zeile 1 ohne NAs, wenn die Werte in Zeile 2 keine NA-Werte sind. Und dann das gleiche für Zeile 1 und 3.

So das Ergebnis für die Zeilen 1-2 sollte 5 und Zeilen 1-3 sollen 4.

Ich habe keine Ahnung, wie sein, um dies zu abgesehen von zu wissen, wie die Länge jeder Zeile zu berechnen:

(apply(df, MARGIN = 1, FUN = function(x) length(x[!is.na(x)]))) 

Jede Hilfe würde sehr geschätzt werden!

+2

Sollte das Ergebnis für die Zeilen 1 und 2 nicht 5 sein? – bgoldst

+1

'" NA "' ist nicht dasselbe wie 'NA'. Ihr Code erstellt eine Zeichenmatrix und keinen Datenrahmen. –

+0

@RichardScriven ist korrekt. Für meine Antwort habe ich meine eigene Definition von "df" erstellt, die die in der Frage gezeigte Druckausgabe reproduziert. Der Aufruf 'cbind()', der in der Frage angezeigt wird, ist wahrscheinlich die Quelle der Inkonsistenz und sollte ignoriert werden. – bgoldst

Antwort

2

Ich würde eine logische Matrix vorberechnen, die darstellt, welche Zellen nicht sind NA, und dann über alle Zeilenindizes über die erste mit einem sapply() Aufruf iterieren. Innerhalb des Lambda können Sie ein logisches UND zwischen der aktuellen Zeile und der ersten Zeile machen, um allgemeine Nicht-NAs zu erhalten, und dann sum() verwenden, um zu zählen, wie viele es gibt.

df <- data.frame(X7=c(1L,1L,1L),X8=c(1L,1L,1L),X9=factor(c(NA,'1','1')),X10=c(1L,1L,1L),X11=c(1L,1L,1L),X12=factor(c('1','1',NA)),X13=factor(c('1',NA,NA)),X14=factor(c(NA,NA,NA))); 
nons <- !is.na(df); 
sapply(seq(2L,len=nrow(df)-1L),function(ri) sum(nons[1L,]&nons[ri,])); 
## [1] 5 4 

Alternativ können Sie die Spaltenindizes in der ersten Reihe vorauszuberechnen, die nicht-NA, und dann aus dem Inneren des Lambda-Anruf intersect() gegen die Indizes in der aktuellen Zeile, die nicht-NA haben.

nons <- !is.na(df); 
nons1 <- unname(which(nons[1L,])); 
sapply(seq(2L,len=nrow(df)-1L),function(ri) length(intersect(nons1,which(nons[ri,])))); 
## [1] 5 4 
+2

Ein anderer Weg wäre 'm <- t (! Is.na (df)); colSums (m [, 1] & m) [- 1] ' –

+1

Mist, gut gemacht @MaratTalipov! Ich dachte kurz über die Möglichkeit nach, eine vollständig vektorisierte Lösung zu erreichen, aber aus irgendeinem Grund entschied ich, dass es nicht möglich war, also entschied ich mich für 'sapply()'. Sie sollten eine Antwort posten; Ich habe es aufgegriffen. – bgoldst

+0

@MaratTalipov so in der Lage sein, zwischen Zeile '2'-' 3' innerhalb des gleichen Codes zu berechnen Ich gehe davon aus, ich müsste es Schleife?. Vielen Dank, Jungs! – Bonono