将重复观察中的不同值设置为NA

时间:2014-03-11 10:20:19

标签: r duplicates duplicate-data na

我有一个数据框(DF),如下所示:

structure(list(ID = c("123", "123", "456", "789", "789"), REPORTER = c("ONE", 
"ONE", "TWO", "THREE", "THREE"), VALUE1 = c("1", "1", "2", "1", 
"1"), VALUE3 = c("2", "1", "1", "2", "1"), VALUE4 = c("2", "1", 
"2", "1", "1")), .Names = c("ID", "REPORTER", "VALUE1", "VALUE3", 
"VALUE4"), row.names = c(1L, 2L, 3L, 5L, 6L), class = "data.frame")

此情况下的唯一性由 ID REPORTER 定义。因此上面的DF包含ID 123和REPORTER ONE以及ID 789和REPORTER THREE的副本。由于我无法确定VALUE1到VALUE4的哪些值是正确的值,我喜欢将所有值设置为NA,这些值在重复内有所不同。

这意味着我首先必须识别包含不同值的VALUE列。这些是设置为NA的。对于其他人,我喜欢保留数据,因为在这里我可以告诉数值是正确的。

预期输出如下:

structure(list(ID = c("123", "123", "456", "789", "789"), REPORTER = c("ONE", 
"ONE", "TWO", "THREE", "THREE"), VALUE1 = c("1", "1", "2", "1", 
"1"), VALUE3 = c(NA, NA, "1", NA, NA), VALUE4 = c(NA, NA, "2", 
"1", "1")), .Names = c("ID", "REPORTER", "VALUE1", "VALUE3", 
"VALUE4"), row.names = c(1L, 2L, 3L, 5L, 6L), class = "data.frame")

目标是确保数据质量。我不想删除问题案例,因为我可以使用不同的值进行分析。但我也不喜欢只使用其中一行,因为如果我选择了错误的值,这会导致错误的结论。

我该怎么做?

2 个答案:

答案 0 :(得分:1)

我认为这就是你要找的东西:

library(reshape2)
DFL <- melt(cbind(rn = 1:nrow(DF), DF), id.vars=c("rn", "ID", "REPORTER"))
DFL$value2 <- ave(DFL$value, DFL[c("ID", "REPORTER", "variable")], 
                  FUN = function(x) {
                    ifelse(length(unique(x)) > 1, NA, x)
                  })
dcast(DFL, rn + ID + REPORTER ~ variable, value.var = "value2")
#   rn  ID REPORTER VALUE1 VALUE3 VALUE4
# 1  1 123      ONE      1   <NA>   <NA>
# 2  2 123      ONE      1   <NA>   <NA>
# 3  3 456      TWO      2      1      2
# 4  4 789    THREE      1   <NA>      1
# 5  5 789    THREE      1   <NA>      1

正如您所看到的,我必须添加一个虚拟的“rn”补充ID变量,以确保dcast不会仅将每个ID + REPORTER组合中的所有值折叠为一行。


更新

对于基本R reshape和上述ave步骤,这实际上也是完全可行的:

DFL <- reshape(DF, direction = "long", 
               varying = grep("VALUE", names(DF)), sep = "")
DFL <- within(DFL, {
  VALUE <- ave(VALUE, ID, REPORTER, time, FUN = function(x) 
    ifelse(length(unique(x)) > 1, NA, x))
})
reshape(DFL)
#      ID REPORTER id VALUE1 VALUE3 VALUE4
# 1.1 123      ONE  1      1   <NA>   <NA>
# 2.1 123      ONE  2      1   <NA>   <NA>
# 3.1 456      TWO  3      2      1      2
# 4.1 789    THREE  4      1   <NA>      1
# 5.1 789    THREE  5      1   <NA>      1

在上面的最后一行中,来自原始attributes语句的reshape使我们不必担心我们需要放入什么参数。: - )

答案 1 :(得分:0)

我创建了一个函数replaceDifferent(),如下所示:

replaceDifferent <- function(vector){
  max <- max(vector)
  min <- min(vector)
  test <- max == min
  if (!test){
    return(NA)
  }
  else{
    return(min(vector))
  }
}

然后我用重塑包装中的熔化()熔化了DF:

DFmelt <- melt(DF, id = c("ID", "REPORTER"))

之后,我能够将新功能应用于融化的数据框ddply()

DFres <- ddply(DFmelt, .(ID, REPORTER, variable), function(x){replaceDifferent(x$value)})

为了获得删除了重复项的结果数据框,我在DFres上调用了dcast():

DFres <- dcast(DFres, ID+REPORTER ~ variable)

这会产生与我要求的输出略有不同的输出,但在我不再需要处理重复项的方式上更好。