如何在数据框中为缺少的数据创建行

时间:2014-06-06 12:30:17

标签: r missing-data

我在不同场景中对人群进行建模。每个场景重复1000次,持续1000年。模型输出是一个包含三列的单个表:重复(R),年(Y),总体大小(N)。 但是,模型输出不包含灭绝事件后多年的数据。例如,如果一个群体在600年中灭绝(N = 0),那么在601到1000年的输出表中我没有得到任何行。

这是一个小例子。假设我有三个场景重复,每个场景重复5年。我可能得到的是:

R   Y   N
1   1   30
1   2   25
1   3   20
1   4   10
1   5   0
2   1   30
2   2   0
3   1   30
3   2   28
3   3   10
3   4   0

structure(list(R = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L, 
3L), Y = c(1L, 2L, 3L, 4L, 5L, 1L, 2L, 1L, 2L, 3L, 4L), N = c(30L, 
25L, 20L, 10L, 0L, 30L, 0L, 30L, 28L, 10L, 0L)), .Names = c("R", 
"Y", "N"), class = "data.frame", row.names = c(NA, -11L))

但我需要的是:

R   Y   N
1   1   30
1   2   25
1   3   20
1   4   10
1   5   0
2   1   30
2   2   0
2   3   0
2   4   0
2   5   0
3   1   30
3   2   28
3   3   10
3   4   0
3   5   0

插入缺失行的最快方法是什么? 可能使用“申请”是一个好主意? 或者可能首先创建一个空数据框

d <- data.frame(Rep=sort(rep(1:1000,1000)), Year=rep(1:1000,1000), NInds=numeric(1000000))

然后覆盖我的值?

5 个答案:

答案 0 :(得分:1)

另一种解决方案,仅限base-R:

r2 <- rep(1:3, each=5)
y2 <- rep(1:5, times=3)
rymissing <- setdiff(paste(r2, y2), paste(df$R, df$Y))
rymissing <- matrix(as.numeric(unlist(strsplit(rymissing, " "))), ncol=2, dimnames=list(NULL, c("R", "Y")), byrow=TRUE)
df2 <- rbind(df, cbind(as.data.frame(rymissing), N=0))
df2 <- df2[order(df2$R, df2$Y),]
row.names(df2) <- NULL
df2

答案 1 :(得分:1)

我会做那样的事情(虽然我不确定你的例子是真的还是只是玩具然后它可能不符合你的要求)。 假设dat是您的数据

dat2 <- data.frame(R = rep(seq_len(3), each = 5), Y = rep(seq_len(5), 3), N = 0)
dat2$N[paste(dat2$R, dat2$Y) %in% paste(dat$R, dat$Y)] <- dat$N

#    R Y  N
# 1  1 1 30
# 2  1 2 25
# 3  1 3 20
# 4  1 4 10
# 5  1 5  0
# 6  2 1 30
# 7  2 2  0
# 8  2 3  0
# 9  2 4  0
# 10 2 5  0
# 11 3 1 30
# 12 3 2 28
# 13 3 3 10
# 14 3 4  0
# 15 3 5  0

答案 2 :(得分:0)

library(plyr)
ddply(DF, .(R), function(df) {
  Y <- seq.int(max(DF$Y))
  N <- df$N
  length(N) <- length(Y)
  N[is.na(N)] <- 0
  data.frame(Y=Y, N=N)
})

#   R Y  N
#1  1 1 30
#2  1 2 25
#3  1 3 20
#4  1 4 10
#5  1 5  0
#6  2 1 30
#7  2 2  0
#8  2 3  0
#9  2 4  0
#10 2 5  0
#11 3 1 30
#12 3 2 28
#13 3 3 10
#14 3 4  0
#15 3 5  0

显然,如果这还不够快,你可以把它翻译成data.table或dplyr。

答案 3 :(得分:0)

来自expand.grid

join + plyr可以在此处提供帮助:

data <- join(expand.grid(R=1:3, Y=1:5), data)
data$N[is.na(data$N)] <- 0

# not necessary but better for comparison to your example
data[order(data$R),]

# not necessary but better for comparison to your example
data[order(data$R),]
##    R Y  N
## 1  1 1 30
## 4  1 2 25
## 7  1 3 20
## 10 1 4 10
## 13 1 5  0
## 2  2 1 30
## 5  2 2  0
## 8  2 3  0
## 11 2 4  0
## 14 2 5  0
## 3  3 1 30
## 6  3 2 28
## 9  3 3 10
## 12 3 4  0
## 15 3 5  0

有趣的是,“纯R”的“胜利”:

ddply
user  system elapsed 
0.003   0.000   0.003 

expand.grid
user  system elapsed 
0.002   0.000   0.002 

pureR
user  system elapsed 
0.001   0.000   0.001 

pureR2
user  system elapsed 
0.002   0.000   0.001 

答案 4 :(得分:0)

仅使用基础R的另一种潜在解决方案:

empty <- data.frame(R=sort(rep(1:3,5)), Y=rep(1:5,3), N=numeric(15))
res <- merge(empty,data,by=c("R","Y"),all=T)[,c(1,2,4)] 
res[is.na(res[,3]),3] <- 0 
names(res) <- c('R','Y','N')