2016-03-30 8 views
2

ich einen Datensatz mit historischen Daten haben, und ich will es in zwei Sätze brechen:Daten Split basierend auf einer logischen Beziehung in R

  1. Der Satz von IDs, die ich ihre Daten für mindestens zwei aufeinander folgenden Jahren .
  2. Es ist Komplement, d. H. Die Menge der IDs, die ich habe ein oder mehrere Jahre Daten von ihnen, aber in nicht aufeinanderfolgenden Jahren.

Zum Beispiel, lassen Sie uns Daten übernehmen gesetzt A:

A = 
ID Year X Y 
1  2010 2 3 
1  2012 4 0 
2  2011 4 3 
2  2012 2 2 
3  2010 3 1 
3  2012 2 1 
3  2013 0 3 

Ich will die Menge B erhalten:

B = 
ID Year X Y 
2  2011 4 3 
2  2012 2 2 
3  2012 2 1 
3  2013 0 3 

B'= 
ID Year X Y 
1  2010 2 3 
1  2012 4 0 
3  2010 3 1 

Beachten Sie, dass ID 3 in beiden B gezeigt und B', weil es hat Aufzeichnungen von aufeinanderfolgenden Jahren und einem einzigen Jahr.

Ich muss das nicht in R tun, ich kann Python auch verwenden. Jede Hilfe wäre willkommen.

Antwort

3

In dplyr,

library(dplyr) 
df %>% group_by(ID) %>% filter(Year %in% c(Year - 1, Year + 1)) 
# Source: local data frame [4 x 4] 
# Groups: ID [2] 
# 
#  ID Year  X  Y 
# (int) (int) (int) (int) 
# 1  2 2011  4  3 
# 2  2 2012  2  2 
# 3  3 2012  2  1 
# 4  3 2013  0  3 

und

df %>% group_by(ID) %>% filter(!Year %in% c(Year - 1, Year + 1)) 
# Source: local data frame [3 x 4] 
# Groups: ID [2] 
# 
#  ID Year  X  Y 
# (int) (int) (int) (int) 
# 1  1 2010  2  3 
# 2  1 2012  4  0 
# 3  3 2010  3  1 

Die Idee ist ziemlich einfach: group_by(ID) jeden ID separat zu bewerten, dann filter nur die Zeilen, die einen Year Wert haben, der eine kleine oder eine Größe größer als alle Werte für die Gruppe. Fügen Sie eine ! hinzu, um die Logik umzukehren und die Zeilen zu erhalten, die diese Bedingung nicht erfüllen.

+0

Sie die Logik übersetzen kann mit so etwas wie 'df [Ordnung (df $ ID),] [fehlenden oder (tapply (df $ Year, df $ ID, Funktion (x zur Basis) {x% in% c (x + 1, x - 1)}))]], aber das ist nicht annähernd so schön. – alistaire

1

Sie können mit Base R versuchen, die Indizes der Zeilen diff

zu finden, die in der Year Spalte 1 Jahr Differenz hat, die Indizes der nächsten Reihe bekommen und sie subsetting.

df[sort(c(which(diff(df$Year) == 1), 
       which(diff(df$Year) == 1) + 1)), ] 

# ID Year X Y 
#3 2 2011 4 3 
#4 2 2012 2 2 
#6 3 2012 2 1 
#7 3 2013 0 3 

und

immer alle Zeilen, die

df[!1:nrow(df) %in% c(which(diff(df$Year) == 1), 
          which(diff(df$Year) == 1) + 1), ] 

# ID Year X Y 
#1 1 2010 2 3 
#2 1 2012 4 0 
#5 3 2010 3 1 
0

Mit data.table

library(data.table) 
setDT(A)[, .SD[Year %in% c(Year-1, Year+1)] , ID] 
# ID Year X Y 
#1: 2 2011 4 3 
#2: 2 2012 2 2 
#3: 3 2012 2 1 
#4: 3 2013 0 3 
nicht Teil der ersten Teilmenge sind

Oder

setDT(A)[, .SD[!Year %in% c(Year-1, Year+1)] , ID] 
# ID Year X Y 
#1: 1 2010 2 3 
#2: 1 2012 4 0 
#3: 3 2010 3 1 

für die beiden Fälle.

Eine weitere Option ist

setDT(A)[A[, {i1 <- .I[(Year - shift(Year, fill= Year[1]))==1] 
       c(i1-1,i1) }, ID]$V1] 
Verwandte Themen