R尝试从单个列创建开始和停止时间

R尝试从单个列创建开始和停止时间,r,R,我是一个初学者,一直被这个看似简单的问题困扰着。我有一个4列的大数据框;id、观察日期、值(alb)和结束日期。一个id在不同日期可能有1到15个左右的观测值。结束日期是事件或审查的时间,每个id一个 id date alb end 1143 2010-03-23 41 2010-12-15 1143 2010-06-29 39 2010-12-15 1144 2008-01-01 34 2009-08-06 11

我是一个初学者,一直被这个看似简单的问题困扰着。我有一个4列的大数据框;id、观察日期、值(alb)和结束日期。一个id在不同日期可能有1到15个左右的观测值。结束日期是事件或审查的时间,每个id一个

    id        date  alb         end
  1143  2010-03-23   41  2010-12-15
  1143  2010-06-29   39  2010-12-15
  1144  2008-01-01   34  2009-08-06 
  1145  2010-03-23   42  2012-10-25 
  1145  2011-01-12   45  2012-10-25
对于使用alb作为时变协变量的生存分析,我尝试为每个观察创建一个事件,并设置开始和停止时间列。我试图创建一个列,其中停止时间是下一个alb观察的开始时间,或者如果该id没有进一步的alb观察,则是结束时间。如下所示:

    id        date  alb         end       start        stop
  1143  2010-03-23   41  2010-12-15  2010-03-23  2010-06-29
  1143  2010-06-29   39  2010-12-15  2010-06-29  2010-12-15
  1144  2008-01-01   34  2009-08-06  2008-01-01  2009-08-06
  1145  2010-03-23   42  2012-10-25  2010-03-23  2011-01-12
  1145  2011-01-12   45  2012-10-25  2011-01-12  2012-10-25
我被困于创建一列停止时间。我在尝试用嵌套的if-else语句创建函数时遇到了麻烦。有人有简单的方法吗?提前谢谢

回复r2evans,这是data.frame的很大一部分,其中来自dplyr操作的一些值返回1970-01-01。(完整数据帧约为130000行)。谢谢

您的数据:

data.frame(
    id=c(        1143,         1143,         1144,         1145,         1145 ),
  date=c("2010-03-23", "2010-06-29", "2008-01-01", "2010-03-23", "2011-01-12" ),
   alb=c(          41,           39,           34,           42,           45 ),
   end=c("2010-12-15", "2010-12-15", "2009-08-06", "2012-10-25", "2012-10-25" )
)
一种技术是使用dplyr:

library(dplyr)
df %>%
    group_by(id) %>%
    mutate(start=date, stop=lead(start, default=end[1]))
## Source: local data frame [5 x 6]
## Groups: id
## 
##     id       date alb        end      start       stop
## 1 1143 2010-03-23  41 2010-12-15 2010-03-23 2010-06-29
## 2 1143 2010-06-29  39 2010-12-15 2010-06-29 2010-12-15
## 3 1144 2008-01-01  34 2009-08-06 2008-01-01 2009-08-06
## 4 1145 2010-03-23  42 2012-10-25 2010-03-23 2011-01-12
## 5 1145 2011-01-12  45 2012-10-25 2011-01-12 2012-10-25
如果您希望仅使用
base
函数执行此操作:

do.call('rbind', by(df, df$id, function(x) {
    cbind(x, start=x$date, stop=lead(x$date, default=x$end[1]))
}))
##          id       date alb        end      start       stop
## 1143.1 1143 2010-03-23  41 2010-12-15 2010-03-23 2010-06-29
## 1143.2 1143 2010-06-29  39 2010-12-15 2010-06-29 2010-12-15
## 1144   1144 2008-01-01  34 2009-08-06 2008-01-01 2009-08-06
## 1145.4 1145 2010-03-23  42 2012-10-25 2010-03-23 2011-01-12
## 1145.5 1145 2011-01-12  45 2012-10-25 2011-01-12 2012-10-25
样本数据:

dat<-read.table(text="
    id        date  alb         end
  1143  2010-03-23   41  2010-12-15
  1143  2010-06-29   39  2010-12-15
  1144  2008-01-01   34  2009-08-06 
  1145  2010-03-23   42  2012-10-25 
  1145  2011-01-12   45  2012-10-25", header=TRUE, stringsAsFactors=FALSE)

数据与
数据类似。表
setDT(dat)[,c('start','stop'):=list(date,shift(date,type='lead',fill=end[1L]),by=id]
谢谢@r2evans,dplyr解决方案很容易阅读,除了每个id的观察序列中的最后一个停止日期显示为1970-01-01-01 04:35:35外,其他方法都可以使用(与POSIXct有关?)。无论如何,现在很容易用正确的结束日期替换。你的数据没有显示异常。你能提供一个小数据集来显示这个问题吗?@MartinWolley,我用你较新的数据运行代码,没有看到“1970”在我的结果中。我知道你不能粘贴所有数据,但如果我看不到问题,我也帮不了你。如果你可以手动处理,那太好了,除非你想通过编程方式修复它,否则不需要将其拖出来。谢谢。当我将所有日期设置为.Date first而不是POSIXct时,问题似乎消失了如前所述。这些答案是否足够?如果足够,请接受一个(这是so的惯例)。供将来参考:最好使用
dput
函数共享数据示例(请参阅)。
dat<-read.table(text="
    id        date  alb         end
  1143  2010-03-23   41  2010-12-15
  1143  2010-06-29   39  2010-12-15
  1144  2008-01-01   34  2009-08-06 
  1145  2010-03-23   42  2012-10-25 
  1145  2011-01-12   45  2012-10-25", header=TRUE, stringsAsFactors=FALSE)
dat$start <- dat$date
dat$stop[!duplicated(dat$id, fromLast = TRUE)] <- dat$end[!duplicated(dat$id, fromLast = TRUE)]
dat$stop[duplicated(dat$id, fromLast = TRUE)] <- dat[duplicated(dat$id), "date"]

dat
#    id       date alb        end      start       stop
#1 1143 2010-03-23  41 2010-12-15 2010-03-23 2010-06-29
#2 1143 2010-06-29  39 2010-12-15 2010-06-29 2010-12-15
#3 1144 2008-01-01  34 2009-08-06 2008-01-01 2009-08-06
#4 1145 2010-03-23  42 2012-10-25 2010-03-23 2011-01-12
#5 1145 2011-01-12  45 2012-10-25 2011-01-12 2012-10-25