2017-07-11 3 views
0

Ich habe einen Datensatz mit drei Spalten, ID, Code, Datum.r Auswahl des Datums basierend auf einer Bedingung

Id   Code     Date 
70329  CD_1020    2004-08-25 
70329  DSW_46    2005-01-18 
70329  AS_712    2009-09-11 
1194167  CK_45    2005-10-13 
1194167  CD_412    2012-04-12 
1194167  DSW_99    2004-08-16 
1194167  CD_456    2010-04-18 

Für jede Id die Spalte Code werden viele verschiedene Codewert enthalten, aber es wird immer enthalten entweder Wert DSW_46 oder DSW_99. Diese beiden Werte, entweder DSW_46 oder DSW_99, sind vorhanden, unabhängig davon, welche anderen Codewerte für jede ID vorhanden sind.

Ziel ist es, basierend auf diesen Kriterien eine vierte Spalte zu erstellen.

step1: Erfassen Sie für jede Id das Datum, an dem die Zeile entweder DSW_46 oder DSW_99 enthält.

Schritt 2:

a) Wenn die es Zeilen früher als die DSW_46 oder DSW_99 Reihen für diese Id, dann das Datum speichern, die Werte entweder DSW_46 oder DSW_99 enthält. Zum Beispiel: Im Fall von Id 70329 gibt es eine Zeile mit dem Wert DSW_46 und das entsprechende Datum ist 2005-01-18, jedoch gibt es eine Zeile vor dem 2005-01-18 für diese ID. Daher sollte die neue Datumsspalte das Datum 2005-01-18

b) Wenn keine Zeilen früher als die Zeilen mit DSW_46- oder DSW_99-Werten vorhanden sind, das Datum der nächsten Beobachtung für diese ID speichern. Zum Beispiel: Im Fall von ID 1194167 hat die Zeile mit DSW_99 einen Datumswert von 2004-08-16 und dies ist der früheste. Es gibt vorher nichts für diese ID (1194167). Die neue Datumsspalte sollte also das Datum 2005.10.13 speichern, welches das nächste Datum nach dem 2004-08-16 ist.

Der letzte erwartete Datensatz wird, wie unten

Id   Code     Date   NewDate 
70329  CD_1020    2004-08-25 2005-01-18 
70329  DSW_46    2005-01-18 2005-01-18 
70329  AS_712    2009-09-11 2005-01-18 
1194167  CK_45    2005-10-13 2005-10-13 
1194167  CD_412    2012-04-12 2005-10-13 
1194167  DSW_99    2004-08-16 2005-10-13 
1194167  CD_456    2010-04-18 2005-10-13 

Hoffnung das macht Sinn gezeigt. Jede Hilfe, wie dies zu erreichen ist, wird sehr geschätzt.

Antwort

1

Versuchen Sie, diese dplyr mit ifelse

Bibliothek (dplyr)

df$Date=as.character(df$Date) 
df1=df %>%arrange(Date)%>%group_by(Id)%>% 
    dplyr::mutate(NewDate = ifelse(sum(Date>=Date[Code%in%c('DSW_46','DSW_99')])==length(Date),Date[2] ,Date[Code%in%c('DSW_46','DSW_99')])) 

output 


Id Code  Date NewDate 
    <int> <chr>  <chr>  <chr> 
1 1194167 DSW_99 2004-08-16 2005-10-13 
2 70329 CD_1020 2004-08-25 2005-01-18 
3 70329 DSW_46 2005-01-18 2005-01-18 
4 1194167 CK_45 2005-10-13 2005-10-13 
5 70329 AS_712 2009-09-11 2005-01-18 
6 1194167 CD_456 2010-04-18 2005-10-13 
7 1194167 CD_412 2012-04-12 2005-10-13 
+0

das funktionierte, werde ich dies ein wenig studieren. Vielen Dank. –

+0

froh, dass es hilft! ~ – Wen

0

Eine andere dplyr Lösung, summarise und left_join verwenden.

dt <- read.table(text = "Id   Code     Date 
70329  CD_1020    2004-08-25 
       70329  DSW_46    2005-01-18 
       70329  AS_712    2009-09-11 
       1194167  CK_45    2005-10-13 
       1194167  CD_412    2012-04-12 
       1194167  DSW_99    2004-08-16 
       1194167  CD_456    2010-04-18", 
       header = TRUE, stringsAsFactors = FALSE) 

library(dplyr) 

dt2 <- dt %>% 
    mutate(Date = as.Date(Date)) %>% 
    group_by(Id) 

dt3 <- dt2 %>% 
    filter(Code %in% c("DSW_46", "DSW_99")) %>% 
    summarise(Date_DSW = min(Date)) 

dt4 <- dt2 %>% 
    filter(!Code %in% c("DSW_46", "DSW_99")) %>% 
    summarise(Date_min = min(Date)) 

dt5 <- dt2 %>% 
    left_join(dt3, by = "Id") %>% 
    left_join(dt4, by = "Id") %>% 
    mutate(NewDate = if_else(Date_DSW > Date_min, Date_DSW, Date_min)) %>% 
    select(Id, Code, Date, NewDate) 
Verwandte Themen