我面临一个简单问题。
我的数据包含以下变量: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_flag
DD
变量
dtadate$DD_flag <- as.numeric(dtadate$DD)
我需要做的是,每当DD_flag
每个标识符DAY
更改一天时,只需将 +1 增加到BCSID
变量。
我认为为我的循环使用折叠的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
解决方案,它几乎给了我正确的输出。
我在这里使用了BCSID
和DAY
。
增量是正确的,但不幸的是,不会重复使用循环其余部分的增量值。
#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
的{{1}}都应增加 +1 。
数据
DD
答案 0 :(得分: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 :(得分: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
# .. ... ... .. .. ... ...
答案 2 :(得分: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
#...