我有数据框
data<-data.frame(id=c("A","A","B","B"), day=c(5,6,1,2), duration=c(12,1440,5,6), obs.period=c(60, 60,100,100))
显示主题ID,事件日,事件持续时间和主题观察期
我想将数据集转换为它将显示每个主题的整个观察期(观察的所有日子),同时在没有观察到事件的日期添加零作为持续时间值
对于上述数据集,这将是这样的:
id day duration obs.period
A 1 0 60
A 2 0 60
A 3 0 60
A 4 0 60
A 5 12 60
A 6 1440 60
A 7 0 60
A 8 0 60
.
.
.
A 60 0 60
B 1 5 100
B 2 6 100
B 3 0 100
B 4 0 100
.
.
.
.
B 100 0 100
有什么想法吗?
答案 0 :(得分:3)
这是使用plyr
包的一种方法。首先,创建一个函数将数据扩展为适当的行数。然后,使用原始数据中的持续时间信息索引到新的data.frame。最后,使用ddply()
调用此函数并对id变量进行分组。
require(plyr)
FUN <- function(x){
dat <- data.frame(
id = x[1,1]
, day = seq_len(x[1,4])
, duration = 0
, obs.period = x[1,4]
)
dat[dat$id == x$id & dat$day == x$day, "duration"] <- x$duration
return(dat)
}
ddply(data, "id", FUN)
id day duration obs.period
1 A 1 0 60
2 A 2 0 60
3 A 3 0 60
4 A 4 0 60
5 A 5 12 60
6 A 6 1440 60
...
61 B 1 5 100
62 B 2 6 100
63 B 3 0 100
...
160 B 100 0 100
答案 1 :(得分:2)
使用正确的索引列创建一个空数据框,但没有值列,然后将其与您的数据合并,并将值列中的NA替换为零。
data<-data.frame(id=c("A","A","B","B"), day=c(5,6,1,2), duration=c(12,1440,5,6), obs.period=c(60, 60,100,100))
zilch=data.frame(id=rep(c("A","B"),each=60),day=1:60)
all=merge(zilch,data, all=T)
all[is.na(all$duration),"duration"]<-0
all[is.na(all$obs.period),"obs.period"]<-0
答案 2 :(得分:1)
我首先要创建一个包含结果的数据框。
ob.period <- with(data, tapply(obs.period, id, max))
n <- sum(ob.period)
result <- data.frame(id=rep(names(ob.period), ob.period),
day=unlist(lapply(ob.period, function(a) 1:a)),
duration=rep(0, n),
obs.period=rep(ob.period,ob.period))
然后我会将id
和day
粘贴在一起,使用match
查找较大数据框中的相关行,然后插入持续时间值。
idday.sm <- paste(data$id, data$day, sep=":")
idday.lg <- paste(result$id, result$day, sep=":")
result$duration[match(idday.sm, idday.lg)] <- data$duration
答案 3 :(得分:1)
以下是plyr
fill1 <- function(df) {
full_period <- 1:100
to_fill <- setdiff(full_period, df$day)
fill_id <- df[1,"id"]
fill_dur <- 0
fill_obs.p <- df[1,"obs.period"]
rows_to_add <- data.frame(id=fill_id, day=to_fill, duration=fill_dur, obs.period=fill_obs.p)
rbind(df,rows_to_add)
}
ddply(data, "id", fill1)
但结果不按ID,持续时间排序。