使用mapply复制记录,然后将输出转换为数据框

时间:2019-06-10 08:21:35

标签: r dataframe

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))

2 个答案:

答案 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)