2011-09-25 42 views
2

我有數據幀變換一個data.frame,卻使缺失值

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 

任何想法?

回答

3

以下是使用plyr軟件包的一種方法。首先,創建一個函數將數據展開爲適當的行數。然後,使用原始數據的持續時間信息將該數據索引到新數據幀中。最後,用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

我會先創建一個數據框來包含結果。

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

然後,我會貼idday在一起,用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 
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,持續時間排序的,但是。

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