2016-09-01 3 views
1

Ich habe eine Datentabelle und ich möchte in Spalte "X" gehen und die ith Wert und die ith + j Wert, da sie eine Bedingung erfüllenFor-Schleife in R, erhalten die i-ten und i-ten + j Zeileneintrag in einer Spalte

ich folgendes sagen Datentabelle „z“ haben:

 z 
     weight height length 
1: 9.436635  1 79.16808 
2: 6.452202  0 86.33170 
3: 4.639220  1 60.52781 
4: 7.941667  1 33.79673 
5: 3.135519  1 68.47615 
6: 7.918595  1 69.77795 
7: 3.950212  1 49.74780 
8: 7.109392  0 58.41541 
9: 5.783499  0 51.30477 
10: 5.056078  1 78.37624 
11: 9.436635  1 51.69053 
12: 6.452202  0 18.39108 
13: 4.639220  1 48.52367 
14: 7.941667  1 20.99888 
15: 3.135519  1 29.77180 

ich etwas schreiben möchte, die mir den ersten Wert in der Höhe Säule geben und die zweiter Wert basierend auf der folgenden Bedingung

Ich möchte eine Schleife schreiben wie:

list1 <- list() 
> for (i in -1:nrow(z)){ 
+  list[[i]] <- z[height == 1 & height+i == 0,] 
+ } 

Also, was ich will, ist die Vorkommen zu erhalten, wo Höhe == 1 und dann der unmittelbar folgende Höhe == 0. ich jedoch festgestellt, dass ich kann, schreib keine Schleife wie diese.

Im Wesentlichen möchte ich alle Zeilen, wo ich eine 1 haben, gefolgt von einer 0 in der Höhe Spalte.

Antwort

4

Wir data.table Methoden verwenden als auch von dem 'i-ten' Element 'height' gleich 1 verglichen mit dem 'i + 1' gleich 0 (shift mit type = "lead" Verwendung)

library(data.table) 
setDT(df1)[height==1 & shift(height, type = "lead")==0] 

Wenn wir benötigen Sie die Zeile 'i' mit 'i + 1', können wir den Zeilenindex (.I) basierend auf der logischen Bedingung erhalten, dann verwenden Sie rep, um die nächste Zeile und Teilmenge der Datenmenge zu erhalten.

i1 <- setDT(df1)[,.I[height==1 & shift(height, type = "lead", fill = 1)==0]] 
df1[rep(i1, each=2) + 0:1] 
# weight height length 
#1: 9.436635  1 79.16808 
#2: 6.452202  0 86.33170 
#3: 3.950212  1 49.74780 
#4: 7.109392  0 58.41541 
#5: 9.436635  1 51.69053 
#6: 6.452202  0 18.39108 
+0

Sorry, wenn es eine dumme Frage ist, aber was macht .Ich mache? –

+0

@Gin_Salmon Wir erhalten den logischen 'TRUE/FALSE' Vektor mit (' height == 1 & ... '). Mit '.I' erhalten wir den Zeilenindex. also ähnlich wie 'which (c (WAHR, FALSCH, FALSCH, WAHR)) ', jedoch wird' .I' sehr nützlich sein, wenn wir eine Gruppe durch Operation machen. Wenn wir 'which' machen, gibt es nur den Index der Zeile innerhalb einer Gruppe, aber' .I' gibt den tatsächlichen Zeilenindex basierend auf dem gesamten Datensatz an. – akrun

2

Dies sollte funktionieren:

df2 <- df1[df1$height==1 & c(diff(df1$height),0)==-1,] 
#> df2 
#  weight height length 
#1: 9.436635  1 79.16808 
#7: 3.950212  1 49.74780 
#11: 9.436635  1 51.69053 

Edit:

Nach der Klärung durch den OP in einigen Kommentaren, scheint es, dass die Zeile unmittelbar nach derjenige, der erfüllt Kriterium sollte auch ausgewählt werden. Eine Möglichkeit, dies zu erreichen

idx <- which(df1$height == 1 & c(diff(df1$height), 0) == -1) 
df1[sort(c(idx,idx+1)),] 
#  weight height length 
# 1: 9.436635  1 79.16808 
# 2: 6.452202  0 86.33170 
# 7: 3.950212  1 49.74780 
# 8: 7.109392  0 58.41541 
#11: 9.436635  1 51.69053 
#12: 6.452202  0 18.39108 

Daten sein könnte:

df1 <- structure(list(weight = c(9.436635, 6.452202, 4.63922, 7.941667, 
3.135519, 7.918595, 3.950212, 7.109392, 5.783499, 5.056078, 9.436635, 
6.452202, 4.63922, 7.941667, 3.135519), height = c(1L, 0L, 1L, 
1L, 1L, 1L, 1L, 0L, 0L, 1L, 1L, 0L, 1L, 1L, 1L), length = c(79.16808, 
86.3317, 60.52781, 33.79673, 68.47615, 69.77795, 49.7478, 58.41541, 
51.30477, 78.37624, 51.69053, 18.39108, 48.52367, 20.99888, 29.7718 
)), .Names = c("weight", "height", "length"), class = "data.frame", 
row.names = c("1:", "2:", "3:", "4:", "5:", "6:", "7:", "8:", "9:", "10:", 
"11:", "12:", "13:", "14:", "15:")) 
1

Wenn Sie die Zeilen mögen, wo height==1 und sofort danach height==0, Sie filter vom dplyr Paket mit lead verwenden können, und lag

library(dplyr) 
result <- z %>% filter((height==1 & lead(height)==0) | (height==0 & lag(height)==1)) 

filter speichert nur die Zeilen, die die Bedingung erfüllen. Die Ergebnisse, die Ihre Daten ist:

print(result) 
## weight height length 
##1 9.436635  1 79.16808 
##2 6.452202  0 86.33170 
##3 3.950212  1 49.74780 
##4 7.109392  0 58.41541 
##5 9.436635  1 51.69053 
##6 6.452202  0 18.39108 
+0

Hallo @aichao, das ist genau das, was ich bin nach leider brauche ich es in data.table. Können Sie dieses Ergebnis in der Datei data.table erhalten? –

+0

@Gin_Salmon: akrun aktualisiert seine Antwort, also ist das, was Sie brauchen. – aichao

0

Sie es versuchen können, mit der which Funktion:

db<-data.frame(height=c(1,0,1,1,1,10,1,0,1,0)) 

for (i in 1:length(db$height)){ 
    print(which(db$height[i]==1 & db$height[i+1]==0)) 

} 

Dies wird Ihnen das erste Auftreten eines solchen Musters.

Verwandte Themen