我有一个如下所示的数据集:
ByYear <- data.frame( V1 = c(2005,2006,2007,2008,2005,2006,2008,2006,2007,2005,2006,2007,2008),
V2 = c(0.5,0.2,1,1.6,2,5,8,4,3,6,8,6,5),
V3 = c('A','A','A','A','B','B','B','C','C','D','D','D','D'))
哪个给了我
> ByYear
V1 V2 V3
1 2005 0.5 A
2 2006 0.2 A
3 2007 1.0 A
4 2008 1.6 A
5 2005 2.0 B
6 2006 5.0 B
7 2008 8.0 B
8 2006 4.0 C
9 2007 3.0 C
10 2005 6.0 D
11 2006 8.0 D
12 2007 6.0 D
13 2008 5.0 D
V1缺少部分年份。这是由于输入数据的错误。我知道这是一个敏感话题,但我知道在这种情况下V1中缺少的一年意味着V2中的值应为0。
有没有办法可以创建一个新的数据集,为任何缺失的年份添加一个零值的行,如下所示:
> ByYear
V1 V2 V3
2005 0.5 A
2006 0.2 A
2007 1.0 A
2008 1.6 A
2005 2.0 B
2006 5.0 B
2007 0.0 B
2008 8.0 B
2005 0.0 C
2006 4.0 C
2007 3.0 C
2008 0.0 C
2005 6.0 D
2006 0.0 D
2007 6.0 D
2008 5.0 D
感谢大家的帮助!
答案 0 :(得分:1)
有几种方法可以做到这一点,最简单的方法就是索引。
让我们先创建一些数据:
R> X <- data.frame(year=seq(2000,2010,by=1), val=0)
R> V <- data.frame(year=c(2003,2005,2007), val=c(1:3))
让我们来看看它
R> X
year val
1 2000 0
2 2001 0
3 2002 0
4 2003 0
5 2004 0
6 2005 0
7 2006 0
8 2007 0
9 2008 0
10 2009 0
11 2010 0
R> V
year val
1 2003 1
2 2005 2
3 2007 3
所以现在我们想要V
注入X
的正确位置。 V
中X
出现的布尔匹配使得这成为可能:
R> X[ X$year %in% V$year, "val"] <- V$val
单独查看X$year %in% V$year
的结果:
R> X$year %in% V$year
[1] FALSE FALSE FALSE FALSE FALSE TRUE FALSE TRUE FALSE FALSE FALSE
现在的结果是:
R> X
year val
1 2000 0
2 2001 0
3 2002 0
4 2003 1
5 2004 0
6 2005 2
7 2006 0
8 2007 3
9 2008 0
10 2009 0
11 2010 0
R>
警告:您需要常规索引才能正常工作。多年,或几个季度或几个月的工作。工作日更难,但也有其他方法。
答案 1 :(得分:1)
使用table
查找缺少的年份/组合。
Frequencies <- with(ByYear, as.data.frame(table(V1, V3)))
MissingValues <- subset(Frequencies, Freq == 0, c(V1, V3))
将V2
的值设置为0
(或NA
或您想要的值),然后将其附加到原始数据集。
MissingValues$V2 <- 0
rbind(ByYear, MissingValues)
答案 2 :(得分:0)
我试图想出一套简单的测试来让Dirk的建议起作用,但重复序列的缺失值阻碍了我。蛮力似乎太有希望了。识别“内部”缺失值,然后识别两端的间隙,其中增加1规则可能会崩溃
for(i in seq_along(ByYear$V1[2:nrow(ByYear)]) ) if(
ByYear$V1[i+1] -ByYear$V1[i] > 1){
ByYear <- rbind(ByYear[1:i, ], c(v1[i]+1,0), ByYear[(i+1):NROW(ByYear), ])}
for(i in seq_along(ByYear$V1[2:nrow(ByYear)]) ) if(
ByYear$V1[i] ==2007 & ByYear$V1[i+1] != 2008 ){
ByYear <- rbind(ByYear[1:i, ], c(2008, 0), ByYear[(i+1):NROW(ByYear), ])}
# I think you need to fill in all the missing 2008's before the missing 2005's
for(i in seq_along(ByYear$V1[2:nrow(ByYear)]) ) if(
ByYear$V1[i] ==2008 & ByYear$V1[i+1] != 2005 ){
ByYear <- rbind(ByYear[1:i, ], c(2005, 0), ByYear[(i+1):NROW(ByYear), ])}
ByYear
V1 V2
1 2005 0.5
2 2006 0.2
3 2007 1.0
4 2008 1.6
5 2005 2.0
6 2006 5.0
7 2007 0.0
71 2008 8.0
9 2005 0.0
8 2006 4.0
91 2007 3.0
12 2008 0.0
10 2005 6.0
11 2006 8.0
121 2007 6.0
13 2008 5.0
答案 3 :(得分:0)
天真(非矢量化)方法:
for (year in 2001:2010) {
if (sum(ByYear["V1"]==year) == 0) {
# add zero value for the found year
}
}
答案 4 :(得分:0)
正如其他人所说,有很多方法可以做到这一点。这是一个使用重塑将为您填充完整矩阵中的孔的事实。
y <- reshape(ByYear, direction = 'wide', timevar = 'V1', v.names = 'V2', idvar = 'V3')
y <- reshape(y, direction = 'long')
y$V3[is.na(y$V3)] <- 0
这是另一个只使用替换。首先,构建一个新的data.frame(df),其中包含完整的V1和V3,但V2设置为0。
uV1 <- unique(ByYear$V1)
uV3 <- unique(ByYear$V3)
df <- data.frame(V1 = rep(uV1, length(uV3)), V3 = rep(uV3, each = length(uV1)), V2 = 0)
这也有助于创建一个新的交互变量,以便您可以拥有每行的唯一标识符。
df$i <- interaction(df$V1, df$V3)
ByYear$i <- interaction(ByYear$V1, ByYear$V3)
现在,在新的data.frame中用来自ByYear的V2替换V2。
df$V2[df$i %in% ByYear$i] <- ByYear$V2