sj <- c("001",'002','003')
st <- c('2017-08-03','2017-08-18','2017-08-30')
diff <- c(350,321,130)
pat <-data.frame(sj,as.Date(st),diff)
我想通过将st每次加1直到差异时间来复制每个患者,这意味着对于sj 001,将有351条记录,如2017-08-03,'2017-08-03'+ 1,' 2017-08-03'+2,...,'2017-08-03'+350。对于其他患者,依此类推。
最后,我需要将输出保存在data.frame(而不是列表)中。
我尝试如下使用mapply,但是输出是一个列表,我不知道必须将其转换为数据帧
expend <- function(USUBJID,st,diff) {
i <- 0
if(diff>=0) {
for (i in seq(0,diff)) {
dt <- data.frame(sj=USUBJID,sepdate=as.Date((st+i),origin = "1970-01-01"))
if (i==0) pol <- dt
else pol <- rbind(pol, dt)
}
}
else {pol <- data.frame(sj=USUBJID,sepdate=st)}
return(pol)
}
ck<- mapply(FUN=expend,pat$USUBJID,pat$st,pat$diff)
我尝试使用以下代码将列表ck转换为数据框,但遇到错误。
ck1 <- cbind.data.frame(ck[rep(seq_along(ck), lengths(ck)),],
res = unlist(ck))
答案 0 :(得分:2)
使用基数R的一种方法:
#split on sj
#and then recreate the data.frame with an lapply function
mylist <- lapply(split(pat, sj), function(x) {
data.frame(sj = x$sj, Date = x$as.Date.st. + 0:x$diff)
})
#bind the list together in a data.frame
do.call(rbind, mylist)
哪个返回:
sj Date
001.1 001 2017-08-03
001.2 001 2017-08-04
001.3 001 2017-08-05
001.4 001 2017-08-06
001.5 001 2017-08-07
001.6 001 2017-08-08
001.7 001 2017-08-09
001.8 001 2017-08-10
001.9 001 2017-08-11
001.10 001 2017-08-12
...
答案 1 :(得分:2)
使用基数R,我们首先可以创建一个函数,将每一行的数据展开diff + 1
次
expand_data <- function(sj, st, diff) {
data.frame(sj = sj,st = seq(st, length.out = diff + 1, by = "1 day"))
}
,然后使用Map
do.call(rbind, Map(expand_data, pat$sj, pat$st, pat$diff))
# sj st
#1 001 2017-08-03
#2 001 2017-08-04
#3 001 2017-08-05
#4 001 2017-08-06
#5 001 2017-08-07
#6 001 2017-08-08
#7 001 2017-08-09
#....
我们也可以使用tidyr::complete
library(dplyr)
library(tidyr)
pat %>%
group_by(sj) %>%
complete(st = seq(st, length.out = diff + 1, by = "1 day")) %>%
select(-diff)
数据
sj <- c("001",'002','003')
st <- as.Date(c('2017-08-03','2017-08-18','2017-08-30'))
diff <- c(350,321,130)
pat <-data.frame(sj,st,diff)