填写R中缺少的重复值

时间:2015-04-15 15:44:15

标签: r dataframe

每个日期我每组有6个重复。正如您在下面数据的子样本中所看到的,某些但不是所有单元格都缺少重复数(1-6)。对于Date集群中的每个Group,我想使用该集群缺少的复制值填充空单元格。例如,如果复制“3”是当前标记的唯一复制品,我想将该簇中剩余的5个单元格标记为“1”,“2”,“4”,“5”和“6”,添加的重复项不按特定顺序排列。

数据我看起来像这样:

   Date   Group Value   Replicate
8/8/2002    A   77.8         3
8/8/2002    A    0  
8/8/2002    A    0  
8/8/2002    A    0  
8/8/2002    A    0  
8/8/2002    A    0  
6/28/2003   A   88.9         1
6/28/2003   A   66.7         3
6/28/2003   A   44.4         4
6/28/2003   A   88.9         6
6/28/2003   A    0  
6/28/2003   A   144.4   
6/28/2006   B   988.9        2
6/28/2006   B    0  
6/28/2006   B    0  
6/28/2006   B    0  
6/28/2006   B    0  
6/28/2006   B    0  
8/5/2006    B   122.2        1
8/5/2006    B   11.1         2
8/5/2006    B   55.6         3
8/5/2006    B   55.6         4
8/5/2006    B   88.9         5
8/5/2006    B   177.8        6

我希望数据看起来像这样

Date    Group   Value   Replicate
8/8/2002    A   77.8      3
8/8/2002    A     0       1
8/8/2002    A     0       2
8/8/2002    A     0       4
8/8/2002    A     0       5
8/8/2002    A     0       6
6/28/2003   A   88.9      1
6/28/2003   A   66.7      3
6/28/2003   A   44.4      4
6/28/2003   A   88.9      6
6/28/2003   A     0       2
6/28/2003   A   144.4     5
6/28/2006   B   988.9     2
6/28/2006   B     0       3
6/28/2006   B     0       4
6/28/2006   B     0       5
6/28/2006   B     0       6
6/28/2006   B     0       1
8/5/2006    B   122.2     1
8/5/2006    B   11.1      2
8/5/2006    B   55.6      3
8/5/2006    B   55.6      4
8/5/2006    B   88.9      5
8/5/2006    B   177.8     6

是否有一种有效的方法可以使用R填充这些丢失的重复值(我的数据集有大约20,000行)?

3 个答案:

答案 0 :(得分:4)

你可以创建一个小的自定义函数来替换你,然后使用像dplyr这样的数据操作包来按日期组来应用函数。这是一个例子:

library(dplyr)

f <- function(x) {
  na_idx <- which(is.na(x))
  unique_elements <- unique(x[-na_idx])
  set_diff <- setdiff(1:6, unique_elements)
  x[na_idx] <- set_diff
  x
}

df %>%
  group_by(Date) %>%
  mutate(Replicate = f(Replicate))  # you could add %>% ungroup if required

#Source: local data frame [24 x 4]
#Groups: Date
#
#        Date Group Value Replicate
#1   8/8/2002     A  77.8         3
#2   8/8/2002     A   0.0         1
#3   8/8/2002     A   0.0         2
#4   8/8/2002     A   0.0         4
#5   8/8/2002     A   0.0         5
#6   8/8/2002     A   0.0         6
#7  6/28/2003     A  88.9         1
#8  6/28/2003     A  66.7         3
#9  6/28/2003     A  44.4         4
#10 6/28/2003     A  88.9         6
#..       ...   ...   ...       ...

你可能用较少的行/输入来编写函数,但我发现它更容易阅读并遵循每行1次操作,因此我将保持原样。


注意:在读取数据时,我使用了fill = TRUE参数,以便用NA填充空单元格(&#34;&#34;条目)。如果您需要将当前数据转换为该格式,您可以执行以下操作:

df[] <- lapply(df, function(x) {
  if(is.character(x)) {
    x[x == ""] <- NA; type.convert(x)
  } else x
  })

这很有用,因为在样本数据中使用&#34;&#34;条目,为数字的列是字符,因此您不能将它们用于数学运算。

答案 1 :(得分:0)

这是另一种应该做的技巧,不使用dplyr或lapply

# http://stackoverflow.com/questions/9665984/how-to-delete-multiple-values-from-a-vector
# your.data is your data
dates <- unique(your.data$Date)
for(date in dates){
    this.date <- your.data[ which(your.data$Date == date), ]
    remove <- this.date$Replicate
    full.rep <- 1:6
    fill <- full.rep [! full.rep %in% remove]
    fill <- sample(fill) # randomize fill
    this.date[ which(!(this.date$Replicate %in% remove)), ]$Replicate <- fill
    your.data[ which(your.data$Date == date), ] <- this.date
}

答案 2 :(得分:0)

使用data.table

require(data.table)
setkey(dt, Date)[is.na(Replicate), 
        Replicate := setdiff(1:6, dt[.(thisDate), Replicate]), 
        by=.(thisDate=Date)]
  • 首先,我们通过Replicate获取NAis.na(Replicate)的索引。

  • dt ReplicateNA的{​​{1}}行中,我们按Date分组(我们将其重命名为另一个名称,以便我们可以在加入下一步)。

  • 因此,对于按Replicate分组NAthisDate的每一行,我们首先通过执行基于连接的子集提取所有Replicate值 - dt[.(thisDate), Replicate]。然后setdiff(1:6, <all Replicate values>)只返回剩余的值。我们使用Replicate

  • 将其分配回Replicate :=

希望这有帮助。