如何用零替换省略的(非NA)数据

时间:2011-11-20 00:40:39

标签: r

我有一个如下所示的数据集:

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

感谢大家的帮助!

5 个答案:

答案 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的正确位置。 VX出现的布尔匹配使得这成为可能:

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