R - 长格式循环按 id 和日期递增 1

R - Long Format Loop increment 1 by id and day

我遇到了一个简单的问题。 我的数据包含以下变量:BCSID id DD MM DAY。 个人标识符、id-day 标识符、日历日、日历月和星期几。 DD_flag 是我需要创建的变量,以更正错误的 DD 日期,因为它们不会根据日期 DAY 递增。

我的数据是这样的

      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

创建我的 DD_flag 变量
dtadate$DD_flag <- as.numeric(dtadate$DD)

我需要做的是简单地将 +1 递增到 DD_flag 变量,每天 DAY 每个标识符发生变化 [=25] =].

我认为在我的循环中使用折叠的 id id 会更简单。

1

我尝试了一个 R 循环但是 我不确定为什么这个解决方案是错误的

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

2

我尝试了 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 时,基于 DDDD_flag 应该增加 +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")

一个选项是在原始对象之外为 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
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
# ..     ...      ... .. .. ...     ...

这可能是一个可行的解决方案

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
#...