【问题标题】:find duplicate, compare a condition, erase one row - with NAs R查找重复项,比较条件,删除一行 - 使用 NAs R
【发布时间】:2019-03-19 17:42:18
【问题描述】:

我正在建立这个问题find duplicate, compare a condition, erase one row r 解决更复杂的情况。

使用以下可重现的示例:

ID1<-c("a1","a4","a6","a6","a5", "a1",NA,"a3", "a2","a2", "a8", "a9", "a9")
ID2<-c("b8","b99","b5","b5","b2","b8" , "b7","b7", "b6","b6",NA,"b9",NA)
Value1<-c(2,5,6,6,2,7, NA,5,NA,4,4,6,6)
Value2<- c(23,51,63,64,23,23,5,6,4,NA,NA,4,NA)
Year<- c(2004,2004,2004,2004,2005,2004,2008,2009, 2008,2009,2014,2016,2016)
df<-data.frame(ID1,ID2,Value1,Value2,Year)

我想选择 ID1 和 ID2 以及 Year 在它们各自的列中具有相同值的行。对于此行,我想比较重复行中的 Value1 和 Value2 ,如果值不同,则擦除列中较高值的行(由于数据结构,这将是明确的 )。

预期结果:

预期

#     ID1  ID2 Value1 Value2 Year
# 1    a1   b8      2     23 2004
# 2    a4  b99      5     51 2004
# 3    a6   b5      6     63 2004

# 5    a5   b2      2     23 2005

# 7  <NA>   b7     NA      5 2008
# 8    a3   b7      5      6 2009
# 9    a2   b6     NA      4 2008
# 10   a2   b6      4     NA 2009
# 11   a8 <NA>      4     NA 2014
# 12   a9   b9      6      4 2016

第一个解决方案:

df_new <- aggregate(.~ID1 + ID2 + Year, df, min, na.action = na.pass)

问题:当 ID 之一为 NA 时,它会删除原始数据

然后我将 NA 更改为字符值

df$ID1[is.na(df$ID1)] <- "Missing_data"
df$ID2[is.na(df$ID2)] <- "Missing_data"

df_new <- aggregate(.~ID1 + ID2 + Year, df, min, na.action = na.pass)

我解决了前一个问题,但我创建了第二个问题。

问题:当一年中有 NA 和其中一个 ID 的 ID(df 中的最后 2 行)时,它的 ID 重复

【问题讨论】:

  • 当您说“擦除具有较小值的行”时,您的意思是Value1Value2?您的预期输出似乎与该描述不符。
  • 另外,为什么您的最后一行 ID1 = a9ID2 = NA 不在您的预期输出中?
  • @AntoniosK 谢谢,我编辑了文本,我的意思是“更高的价值”。最后一行不在预期输出中,因为与前一行重复。
  • 当你有Value1Value2而不是一个value时,“更高的价值”是没有意义的。如果除了 A 行有 Value1 = 23Value2 = 2 和 B 行有 Value1 = 2Value2 = 23 之外,你有两行相同,你想保留 A 行还是 B 行(为什么)?或者您想混合和匹配行,保持每列中的较低值,以Value1 = 2Value2 = 2 结尾? (这听起来更像是聚合而不是删除重复项。)
  • @Gregor 感谢您的评论。我重述了这个问题。函数 min 汇总了我想要的完整案例。问题在于包含 NA 的比较。

标签: r if-statement duplicates aggregate


【解决方案1】:

这是dplyr 解决方案:

library(dplyr)

df %>%
  arrange(Value2) %>%             
  distinct(ID1, ID2, Year, .keep_all = T) %>%    
  arrange(ID2) %>%
  distinct(ID1, Year, .keep_all = T) %>%  
  arrange(ID1) %>%
  distinct(ID2, Year, .keep_all = T)

#      ID1  ID2 Value1 Value2 Year
# 1    a1   b8      2     23 2004
# 2    a2   b6     NA      4 2008
# 3    a2   b6      4     NA 2009
# 4    a3   b7      5      6 2009
# 5    a4  b99      5     51 2004
# 6    a5   b2      2     23 2005
# 7    a6   b5      6     63 2004
# 8    a8 <NA>      4     NA 2014
# 9    a9   b9      6      4 2016
# 10 <NA>   b7     NA      5 2008

当我们按Value2 排列时,Value 的较小值将位于顶部,distinct 将删除所有重复项并保留它找到的第一行(即具有较小Value2 的行)。

当我们按ID1ID2 排列时,NA 值将位于底部,如果重复,distinct 将排除它们。

请注意,我仅使用 Value2 来保留较小的值,因为我仍然不清楚您所说的“值”是什么意思。

【讨论】:

  • 您好,我不明白您的注意事项。通过价值,我的意思是较小的数字。我希望始终在同一列数字(Value1 或 Value2)内进行比较。两列(Value1 和 Value2)之间的数字永远不需要比较。
  • 该解决方案不适用于具有多个 NA 的数据,因为它只保留其中一个
  • 您必须在您的帖子中添加这样的示例,以便我可以更新我的答案。如果您发布的数据集不能代表您的真实案例,则会出现错误。
猜你喜欢
  • 2019-03-19
  • 2021-01-13
  • 1970-01-01
  • 1970-01-01
  • 2022-12-18
  • 1970-01-01
  • 2012-06-05
  • 2015-07-15
  • 2019-12-10
相关资源
最近更新 更多