2015-07-11 61 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 
#...