我想为数据框中的每个主题ID添加一个额外的行(如下所示)。此行应为TIME=0
和DV=0
。其他列中的其他值应保持不变。数据框如下所示:
ID TIME DV DOSE pH
1 1 5 50 4.6
1 5 10 50 4.6
2 1 6 100 6.0
2 7 10 100 6.0
添加额外的行后,它应如下所示:
ID TIME DV DOSE pH
1 0 0 50 4.6
1 1 5 50 4.6
1 5 10 50 4.6
2 0 0 100 6.0
2 1 6 100 6.0
2 7 10 100 6.0
我怎样才能在R中实现这个目标?
答案 0 :(得分:5)
试试这个:
#dummy data
df <- read.table(text="ID TIME DV DOSE pH
1 1 5 50 4.6
1 5 10 50 4.6
2 1 6 100 6.0
2 7 10 100 6.0",header=TRUE)
#data with zeros
df1 <- df
df1[,c(2,3)] <- 0
df1 <- unique(df1)
#rowbind and sort
res <- rbind(df,df1)
res <- res[order(res$ID,res$TIME),]
res
# ID TIME DV DOSE pH
# 11 1 0 0 50 4.6
# 1 1 1 5 50 4.6
# 2 1 5 10 50 4.6
# 31 2 0 0 100 6.0
# 3 2 1 6 100 6.0
# 4 2 7 10 100 6.0
答案 1 :(得分:5)
这是另一种可能的data.table
解决方案
library(data.table)
setDT(df)[, .SD[c(1L, seq_len(.N))], ID][,
indx := seq_len(.N), ID][indx == 1L, 2:3 := 0][]
# ID TIME DV DOSE pH indx
# 1: 1 0 0 50 4.6 1
# 2: 1 1 5 50 4.6 2
# 3: 1 5 10 50 4.6 3
# 4: 2 0 0 100 6.0 1
# 5: 2 1 6 100 6.0 2
# 6: 2 7 10 100 6.0 3
答案 2 :(得分:3)
我将索引从c(.N+1, 1:.N)
更改为c(1L, 1:.N)
(来自@David Arenburg的帖子),因为这样更容易: - )
library(data.table)
setDT(df)[, .SD[c(1L,1:.N)], by=ID][, 2:3 := .SD*(!duplicated(.SD,
fromLast=TRUE))+0L, .SDcols=2:3][]
# ID TIME DV DOSE pH
#1: 1 0 0 50 4.6
#2: 1 1 5 50 4.6
#3: 1 5 10 50 4.6
#4: 2 0 0 100 6.0
#5: 2 1 6 100 6.0
#6: 2 7 10 100 6.0
或者您可以使用通过引用更新的set
(如果列数很多)
DT <- setDT(df)[, .SD[c(1L, 1:.N)], by=ID]
indx <- DT[, !duplicated(.SD, fromLast=TRUE), .SDcols=2:3]
for(j in 2:3){
set(DT, i=NULL, j=j, value= DT[[j]]*(indx+0L))
}
答案 3 :(得分:2)
使用plyr
的简明方法:
library(plyr)
ldply(split(df, df$ID), function(u){x=u[1,];x[c("DV","TIME")]=0;rbind(x,u)})
# .id ID TIME DV DOSE pH
#1 1 1 0 0 50 4.6
#2 1 1 1 5 50 4.6
#3 1 1 5 10 50 4.6
#4 2 2 0 0 100 6.0
#5 2 2 1 6 100 6.0
#6 2 2 7 10 100 6.0