2015-07-11 85 views
1

我面臨一個簡單問題的問題。 我的數據包含以下變量:BCSID id DD MM DAY。 個人標識符,身份標識日期標識符,日曆日,日曆月和星期幾。 DD_flag是我需要創建的變量,以便糾正DD錯誤的日期,因爲它們不會根據當天的DAY增加。R - 長格式循環增量1按ID和日期

我的數據是這樣的

 BCSID  id DD MM DAY 
200 B10011Q B10011Q2 24 10 2 
201 B10011Q B10011Q2 24 10 2 
202 B10011Q B10011Q2 24 10 2 
203 B10011Q B10011Q2 24 10 2 
204 B10011Q B10011Q2 24 10 2 
205 B10011Q B10011Q2 24 10 2 
206 B10011Q B10011Q2 24 10 2 
207 B10011Q B10011Q3 24 10 3 
208 B10011Q B10011Q3 24 10 3 
209 B10011Q B10011Q3 24 10 3 
210 B10011Q B10011Q3 24 10 3 
211 B10011Q B10011Q3 24 10 3 
212 B10011Q B10011Q3 24 10 3 
213 B10011Q B10011Q3 24 10 3 
214 B10011Q B10011Q3 24 10 3 

我會根據DD

dtadate$DD_flag <- as.numeric(dtadate$DD) 

我需要做的是簡單的增加+1到TH DD_flag變量中的每個創建我DD_flag變量時間DAY更改爲每個標識符BCSID

我認爲在我的循環中使用摺疊編號爲id可能會更簡單。

我嘗試了R迴路但 我不知道爲什麼這個解決方案是錯誤的

for(i in 2:nrow(dtadate)){ 
    if(dtadate$id[i] == dtadate$id[i-1]) 
    { dtadate$DD_flag[i] = dtadate$DD_flag[i] + 1 } 
} 

我嘗試了Rcpp解決方案,幾乎使我是正確的輸出。 這裏我使用了BCSIDDAY

增量是正確的,但不幸的是不會在循環的其餘部分重新使用遞增的值。

#include <Rcpp.h> 
using namespace Rcpp; 

// [[Rcpp::export]] 
NumericVector TimeAddOneCpp(CharacterVector idDay, CharacterVector Day, NumericVector time) { 

    int n = idDay.size(); 
    int len = n ; 

    for (int i = 1; i < len; ++i) { 
    if((idDay[i] == idDay[i - 1]) & 
     (Day[i] != Day [i - 1]) 
     ) 
     time[i] = time[i-1] + 1; 
    } 

    return time; 
} 

功能

TimeAddOneCpp(idDay = dtadate$BCSID, Day = dtadate$DAY, time = dtadate$DD_flag) 

預計輸出

我想輸出下面

 BCSID  id DD MM DAY DD_flag 
200 B10011Q B10011Q2 24 10 2  24 
201 B10011Q B10011Q2 24 10 2  24 
202 B10011Q B10011Q2 24 10 2  24 
203 B10011Q B10011Q2 24 10 2  24 
204 B10011Q B10011Q2 24 10 2  24 
205 B10011Q B10011Q2 24 10 2  24 
206 B10011Q B10011Q2 24 10 2  24 
207 B10011Q B10011Q3 24 10 3  25 
208 B10011Q B10011Q3 24 10 3  25 
209 B10011Q B10011Q3 24 10 3  25 
210 B10011Q B10011Q3 24 10 3  25 
211 B10011Q B10011Q3 24 10 3  25 
212 B10011Q B10011Q3 24 10 3  25 
213 B10011Q B10011Q3 24 10 3  25 
214 B10011Q B10011Q3 24 10 3  25 
215 B10011Q B10011Q3 24 10 3  25 
216 B10011Q B10011Q3 24 10 3  25 
217 B10011Q B10011Q3 24 10 3  25 
218 B10011Q B10011Q3 24 10 3  25 
219 B10011Q B10011Q3 24 10 3  25 
220 B10011Q B10011Q4 24 10 4  26 
... 

所以每次DAY改變每個BCSID,該DD_flag根據DD應遞增+1

數據

dta = structure(list(BCSID = c("B10011Q", "B10011Q", "B10011Q", "B10011Q", 
        "B10011Q", "B10011Q", "B10011Q", "B10011Q", "B10011Q", "B10011Q", 
        "B10011Q", "B10011Q", "B10011Q", "B10011Q", "B10011Q", "B10011Q", 
        "B10011Q", "B10011Q", "B10011Q", "B10011Q", "B10011Q", "B10011Q", 
        "B10011Q", "B10011Q", "B10011Q", "B10011Q", "B10011Q", "B10011Q", 
        "B10011Q", "B10011Q", "B10011Q", "B10011Q", "B10015U", "B10015U", 
        "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", 
        "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", 
        "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", 
        "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", 
        "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", 
        "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", 
        "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", 
        "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", "B10015U", 
        "B10017W", "B10017W", "B10017W", "B10017W", "B10017W", "B10017W", 
        "B10017W", "B10017W", "B10017W", "B10017W", "B10017W", "B10017W", 
        "B10017W", "B10017W", "B10017W", "B10017W", "B10017W", "B10017W", 
        "B10017W"), id = c("B10011Q2", "B10011Q2", "B10011Q2", "B10011Q2", 
             "B10011Q2", "B10011Q2", "B10011Q2", "B10011Q3", "B10011Q3", "B10011Q3", 
             "B10011Q3", "B10011Q3", "B10011Q3", "B10011Q3", "B10011Q3", "B10011Q3", 
             "B10011Q3", "B10011Q3", "B10011Q3", "B10011Q3", "B10011Q4", "B10011Q4", 
             "B10011Q4", "B10011Q4", "B10011Q4", "B10011Q4", "B10011Q4", "B10011Q4", 
             "B10011Q4", "B10011Q4", "B10011Q5", "B10011Q5", "B10015U1", "B10015U1", 
             "B10015U1", "B10015U1", "B10015U1", "B10015U1", "B10015U1", "B10015U1", 
             "B10015U1", "B10015U1", "B10015U1", "B10015U1", "B10015U1", "B10015U2", 
             "B10015U2", "B10015U2", "B10015U2", "B10015U2", "B10015U2", "B10015U2", 
             "B10015U2", "B10015U2", "B10015U2", "B10015U2", "B10015U2", "B10015U2", 
             "B10015U2", "B10015U2", "B10015U2", "B10015U3", "B10015U3", "B10015U3", 
             "B10015U3", "B10015U3", "B10015U3", "B10015U3", "B10015U3", "B10015U3", 
             "B10015U4", "B10015U4", "B10015U4", "B10015U4", "B10015U4", "B10015U4", 
             "B10015U4", "B10015U4", "B10015U4", "B10015U4", "B10015U4", "B10015U4", 
             "B10017W1", "B10017W1", "B10017W1", "B10017W1", "B10017W1", "B10017W1", 
             "B10017W1", "B10017W1", "B10017W1", "B10017W1", "B10017W1", "B10017W1", 
             "B10017W1", "B10017W1", "B10017W1", "B10017W1", "B10017W1", "B10017W1", 
             "B10017W1"), DD = c("24", "24", "24", "24", "24", "24", "24", 
                  "24", "24", "24", "24", "24", "24", "24", "24", "24", "24", "24", 
                  "24", "24", "24", "24", "24", "24", "24", "24", "24", "24", "24", 
                  "24", "24", "24", "1", "1", "1", "1", "1", "1", "1", "1", "1", 
                  "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", 
                  "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", 
                  "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", 
                  "1", "1", "13", "13", "13", "13", "13", "13", "13", "13", "13", 
                  "13", "13", "13", "13", "13", "13", "13", "13", "13", "13"), 
      MM = c("10", "10", "10", "10", "10", "10", "10", "10", "10", 
        "10", "10", "10", "10", "10", "10", "10", "10", "10", "10", 
        "10", "10", "10", "10", "10", "10", "10", "10", "10", "10", 
        "10", "10", "10", "8", "8", "8", "8", "8", "8", "8", "8", 
        "8", "8", "8", "8", "8", "8", "8", "8", "8", "8", "8", "8", 
        "8", "8", "8", "8", "8", "8", "8", "8", "8", "8", "8", "8", 
        "8", "8", "8", "8", "8", "8", "8", "8", "8", "8", "8", "8", 
        "8", "8", "8", "8", "8", "8", "6", "6", "6", "6", "6", "6", 
        "6", "6", "6", "6", "6", "6", "6", "6", "6", "6", "6", "6", 
        "6"), DAY = c("2", "2", "2", "2", "2", "2", "2", "3", "3", 
           "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "4", 
           "4", "4", "4", "4", "4", "4", "4", "4", "4", "5", "5", "1", 
           "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", 
           "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", 
           "2", "2", "2", "2", "3", "3", "3", "3", "3", "3", "3", "3", 
           "3", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", 
           "4", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", 
           "1", "1", "1", "1", "1", "1", "1", "1")), .Names = c("BCSID", 
                        "id", "DD", "MM", "DAY"), row.names = 200:300, class = "data.frame") 
+0

你切斷所需的輸出後的6行。你可以擴展它,所以我們可以看到至少前15行? –

+0

@PierreLafortune - 完成 – giacomo

+1

好吧,它看起來像你按月分組。你可能需要''dtadate%>%group_by(MM)%>%mutate(DD_flag = c(0,cumsum(diff(DD)))+ DD)' –

回答

1
library(dplyr) 
dta %>% 
    group_by(BCSID) %>% 
    mutate(DD_flag = c(0, cumsum(diff(as.integer(DAY))))+as.integer(DD)) 

# Source: local data frame [101 x 6] 
# Groups: BCSID 
# 
#  BCSID  id DD MM DAY DD_flag 
# 1 B10011Q B10011Q2 24 10 2  24 
# 2 B10011Q B10011Q2 24 10 2  24 
# 3 B10011Q B10011Q2 24 10 2  24 
# 4 B10011Q B10011Q2 24 10 2  24 
# 5 B10011Q B10011Q2 24 10 2  24 
# 6 B10011Q B10011Q2 24 10 2  24 
# 7 B10011Q B10011Q2 24 10 2  24 
# 8 B10011Q B10011Q3 24 10 3  25 
# 9 B10011Q B10011Q3 24 10 3  25 
# 10 B10011Q B10011Q3 24 10 3  25 
# ..  ...  ... .. .. ...  ... 
1

一種選擇是將原來的對象之外創建DD_flag所需的值,然後將它們合併。讓我們把你貼z上的數據幀。因此:

flags <- data.frame(id = unique(z$id), DD_flag = seq(length(unique(z$id)))) 
z2 <- merge(z, flags, all.x = TRUE) 

該方法假定您不關心這些標誌的順序。如果你這樣做,你只需要在第一行中或之前按照期望的順序放置id變量的唯一值。

該方法還假定您在合併時尚未在z中使用名爲DD_flag的變量。如果你這樣做,你可能只是在合併之前運行此:

z$DD_flag <- NULL 
1

這可能是一個可行的解決方案

library(data.table) 
setDT(dta) 
out = rbindlist(
     lapply(split(dta, dta$BCSID), 
     function(x){ x[, DD_flag := (as.numeric(x$DD) + .GRP)-1, by = DAY]})) 

#> out 
#  BCSID  id DD MM DAY DD_flag 
#1: B10011Q B10011Q2 24 10 2  24 
#2: B10011Q B10011Q2 24 10 2  24 
#3: B10011Q B10011Q2 24 10 2  24 
#4: B10011Q B10011Q2 24 10 2  24 
#5: B10011Q B10011Q2 24 10 2  24 
#6: B10011Q B10011Q2 24 10 2  24 
#7: B10011Q B10011Q2 24 10 2  24 
#8: B10011Q B10011Q3 24 10 3  25 
#9: B10011Q B10011Q3 24 10 3  25 
#10: B10011Q B10011Q3 24 10 3  25 
#11: B10011Q B10011Q3 24 10 3  25 
#12: B10011Q B10011Q3 24 10 3  25 
#13: B10011Q B10011Q3 24 10 3  25 
#14: B10011Q B10011Q3 24 10 3  25 
#15: B10011Q B10011Q3 24 10 3  25 
#...