2016-05-19 2 views
0

ich einen Datensatz haben, die wie folgt aussieht:R Einsturz Datumsfelder mit Bedingungen

df=data.frame(c(1,2,2,2,3,4,4), 
as.Date(c("2015-01-29","2015-02-02","2015-02-02","2015-02-02","2014-05-04","2014-05-04","2014-05-04")), 
as.Date(c("2010-10-01","2009-09-01","2014-01-01","2014-02-01","2009-01-01","2014-03-01","2013-03-01")), 
as.Date(c("2016-04-30","2013-12-31","2014-01-31","2016-04-30","2014-02-28","2014-08-31","2013-05-01"))); 
names(df)=c('id','poi','start','end') 

> df 
    id  poi  start  end 
1 1 2015-01-29 2010-10-01 2016-04-30 
2 2 2015-02-02 2009-09-01 2013-12-31 
3 2 2015-02-02 2014-01-01 2014-01-31 
4 2 2015-02-02 2014-02-01 2016-04-30 
5 3 2014-05-04 2009-01-01 2014-02-28 
6 4 2014-05-04 2014-03-01 2014-08-31 
7 4 2014-05-04 2013-03-01 2013-05-01 

Die Start- und Enddaten sind Versicherung beginnen und Enddaten, manchmal gibt es gleiche Startdaten für mehrere Zeilen, weil sie betreffen zu verschiedenen Versicherungsarten. Ich bin daran interessiert, diese IDs zu behalten, die konsistente Versicherung Berichterstattung ein Jahr vor und nach der Poi hat. Jede ID kann nur 1 Poi haben.

Meine Ausgabe wäre eine Liste von IDs, die Versicherungsschutz 1 Jahr vor und 1 Jahr nach der Poi haben. In diesem Fall würde es die IDs 3 und 4 ausschließen, da sie 1 Jahr nach der Poi keine Abdeckung haben.

ids=c(1,2) 

Ich habe Folgendes versucht, aber ehrlich gesagt keine Ahnung davon, wie ich erreichen kann, was ich will.

Jede Hilfe wird wirklich geschätzt.

library(rehape2) 
df.melt=melt(df, 
      id=c("id","poi")) 

df.melt=mutate(df.melt, flag=ave(id,id,variable,FUN=seq_along)) 
df.melt=mutate(df.melt, variable=paste(variable,flag,sep ="_")) 
df.cast=dcast(df.melt, id+poi~variable) 
+1

was genau wäre Ihr erwartetes Ergebnis? – agenis

+0

@agenis Ich habe die Frage behoben, um die erwartete Ausgabe einzuschließen. Vielen Dank! – user3641630

+0

@ user3641630 also bin ich klar, dass Sie eine Liste von POI wollen, wo das Bettdatum und das Enddatum größer als ein Jahr vom POI entfernt sind? – SeldomSeenSlim

Antwort

1

Wenn Sie ev wollen aluate die Zeilen einzeln, mit dplyr und lubridate:

library(dplyr) 
library(lubridate) 

# filter to only rows with a POI within the desired range 
df %>% filter(poi - years(1) >= start, 
       poi + years(1) <= end) 

# id  poi  start  end 
# 1 1 2015-01-29 2010-10-01 2016-04-30 
# 2 2 2015-02-02 2014-02-01 2016-04-30 

Wenn Sie lieber die Zeilen alle für einen ID bewerten würde, vielleicht so etwas wie

# group to summarize IDs separately 
df %>% group_by(id, poi) %>% 
    # collapse rows to min start and max end for each ID 
    summarise(start = min(start), 
       end = max(end)) %>% 
    # filter to only rows with a POI within the desired range 
    filter(poi - years(1) >= start, 
      poi + years(1) <= end) 

# Source: local data frame [2 x 4] 
# Groups: id [2] 
# 
#  id  poi  start  end 
# (dbl)  (date)  (date)  (date) 
# 1  1 2015-01-29 2010-10-01 2016-04-30 
# 2  2 2015-02-02 2009-09-01 2016-04-30 

Ein solcher Ansatz Deckungslücken übersehen würde, obwohl wenn das möglich ist. Wenn dies der Fall ist, können lubridate::interval und int_overlaps nützlich sein, um Zeilen sorgfältig zu kondensieren.

+0

Ich muss auch die Coverage-Lücke in Betracht ziehen. Danke, das gibt mir eine wirklich gute Plattform um anzufangen. – user3641630

0

Ich denke, das tut, was Sie wollen, aber wenn es nicht der Fall ist, sollten Sie in der Lage sein, nur mit den größer und kleiner als Zeichen zu spielen:

df[(df$poi-df$start)/365>1&(df$end-df$poi)/365>1,] 

> df[(df$poi-df$start)/365>1&(df$end-df$poi)/365>1,] 
    id  poi  start  end 
1 1 2015-01-29 2010-10-01 2016-04-30 
4 2 2015-02-02 2014-02-01 2016-04-30 

Dies gibt Ihnen die zwei Linien des df, die den Wert, den Sie wollen ..

Jetzt nur noch die Ids halten:

df$id[(df$poi-df$start)/365>1&(df$end-df$poi)/365>1] 
df$id[(df$poi-df$start)/365>1&(df$end-df$poi)/365>1] 
[1] 1 2 
Verwandte Themen