我有一个数据框(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")
目标是确保数据质量。我不想删除问题案例,因为我可以使用不同的值进行分析。但我也不喜欢只使用其中一行,因为如果我选择了错误的值,这会导致错误的结论。
我该怎么做?
答案 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)
这会产生与我要求的输出略有不同的输出,但在我不再需要处理重复项的方式上更好。