2014-10-16 145 views
3

我有一個數據框,我基本上有一個ID#,一年和一個狀態碼。下面是它的一個例子:if語句的匹配值基於R中的日期

> df <- data.frame(ID=c(100,100,100,102,102,102), 
        Year=c(2010,2011,2012,2010,2011,2012), 
        Status=c("c","d","d","d","c","c")) 
> df 
    ID Year Status 
1 100 2010  c 
2 100 2011  d 
3 100 2012  d 
4 102 2010  d 
5 102 2011  c 
6 102 2012  c 

我想基於ID#的地位,作爲一個二進制添加第4列(df$def),然而,一旦狀態爲‘d’我需要隨身攜帶儘管地位可能變爲「c」,但剩下的幾年。我可以寫簡單的IF語句,使其「0」爲「c」,「1」爲1,但我無法分解前進的日期。

我想最後的表看起來像這樣:

df 
    ID Year Status Def 
1 100 2010  c 0 
2 100 2011  d 1 
3 100 2012  d 1 
4 102 2010  d 1 
5 102 2011  c 1 
6 102 2012  c 1 

感謝您的幫助!

回答

1

你可以使用:

within(df, {def<- ave(Status=='d', ID, FUN=cumsum);def[def>1] <- 1 }) 
    # ID Year Status def 
    #1 100 2010  c 0 
    #2 100 2011  d 1 
    #3 100 2012  d 1 
    #4 102 2010  d 1 
    #5 102 2011  c 1 
    #6 102 2012  c 1 

或者更大的數據集,你可以使用data.table

library(data.table) 
    setDT(df)[, Def:=cumsum(Status=='d'), by=ID][ Def>1, Def:=1][] 
    # ID Year Status Def 
#1: 100 2010  c 0 
#2: 100 2011  d 1 
#3: 100 2012  d 1 
#4: 102 2010  d 1 
#5: 102 2011  c 1 
#6: 102 2012  c 1 

或者你可以使用split

res <- unsplit(lapply(split(df, df$ID), function(x) { 
       indx <- which(x$Status=='d') 
       x$Def <- 0 
       if(length(indx)>0){ 
       indx1 <- indx[1] 
       x$Def[indx1:nrow(x)] <- 1 
       } 
       x}), df$ID) 



    res 
    # ID Year Status Def 
    #1 100 2010  c 0 
    #2 100 2011  d 1 
    #3 100 2012  d 1 
    #4 102 2010  d 1 
    #5 102 2011  c 1 
    #6 102 2012  c 1 
+0

頂部代碼工作最好與我的代碼。不知道底部的一個,我的DF有大約6萬個ID,並且要花很長時間才能運行。謝謝您的幫助! – nciaf 2014-10-16 16:29:59

+0

@nciaf我認爲基於ave的解決方案與使用一些附加檢查的'split'相比會更快。 – akrun 2014-10-16 16:46:05

+0

@nciaf考慮'data.table'方法(更新),會更快。 – akrun 2014-10-16 16:57:55

1

您可以嘗試使用該功能by()通過ID獲得累積和(不允許它超過1)

df$def <- ifelse(df$Status == "c", 0, 1) 
df$def <- pmin(1, unlist(by(df$def, df$ID, cumsum))) 
1

這裏的另一種方式:

within(df, { 
    Def <- 
    ave(as.character(Status), ID, 
     FUN=function(x) ifelse(seq_along(x) < which.max(x == 'd'), 0, 1)) 
}) 
# ID Year Status Def 
# 1 100 2010  c 0 
# 2 100 2011  d 1 
# 3 100 2012  d 1 
# 4 102 2010  d 1 
# 5 102 2011  c 1 
# 6 102 2012  c 1