【问题标题】:Comparing two columns in a dataframe using R使用 R 比较数据框中的两列
【发布时间】:2021-10-27 03:25:51
【问题描述】:

我正在尝试比较数据框中的两列以查找两列不相等的行。

我愿意:

df %>% filter(column1 != column2)

这将为我提供两列中都存在值且不相等的情况(例如 column1 = 5,column2 = 6)

但是它不会给出其中一个值为 NA 的情况(例如 column1 = NA,column2 = 7)

如何将后一种情况包含在过滤器函数中?

谢谢

【问题讨论】:

  • 如果您包含一个简单的reproducible example,其中包含可用于测试和验证可能解决方案的示例输入和所需输出,则更容易为您提供帮助。

标签: r dplyr


【解决方案1】:

或者使用xor:

df %>% filter(a != b | xor(is.na(a), is.na(b)))

或者正如@thelatemail 提到的,您可以使用 Base R:

df[which(df$a != df$b | xor(is.na(df$a), is.na(df$b))),]

或者正如@runr 提到的,你可以在Base R 中尝试subset

subset(df, a != b | xor(is.na(a), is.na(b)))

【讨论】:

  • 我认为这段代码将包括 (NA, NA),我不希望在最终的 df 中包含它们,因为它们对于我的目的来说是“相等的”
  • @MLE 立即查看,xor
  • @MLE xoror,但不是 and。因此,如果两者中的一个是NA,它会选择,但如果两者都是,则不会选择
  • 很好的逻辑。有趣的是,这个选择只适用于dplyr::filter,因为NA 选择被删除了。必须为[] 选择添加which() - df[which(df$a != df$b | xor(is.na(df$a), is.na(df$b))),]
  • 也只是 subset(df, a != b | xor(is.na(a), is.na(b))) 而不是 with() 使用基本 R 完成这项工作
【解决方案2】:

您可以将它们包含在 OR (|) 条件中 -

library(dplyr)

df <- data.frame(a = c(1, 2, NA, 4, 5), b = c(NA, 2, 3, 4, 8))

df %>% filter(a != b | is.na(a) | is.na(b))

#   a  b
#1  1 NA
#2 NA  3
#3  5  8

另一种选择是将NA 值更改为字符串“NA”,然后只使用a != b 应该可以工作。

df %>% 
  mutate(across(.fns = ~replace(., is.na(.), 'NA'))) %>%
  filter(a != b) %>%
  type.convert(as.is = TRUE) 

【讨论】:

  • 这样的话,(NA, NA) 不会被包括进来吗? (我不想要,因为它们对于我的目的是“平等的”)鉴于 NA == NA 是 NA 不是 TRUE。只是在寻找一个干净的解决方案
  • @MLE 查看更新后的答案。带有示例输出的示例数据框将有助于更好地理解问题。
【解决方案3】:

我们可以使用if_any

library(dplyr)
df %>% 
   filter(a != b | if_any(everything(), is.na))
   a  b
1  1 NA
2 NA  3
3  5  8

数据

df <- structure(list(a = c(1, 2, NA, 4, 5), b = c(NA, 2, 3, 4, 8)),
 class = "data.frame", row.names = c(NA, 
-5L))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-23
    • 1970-01-01
    相关资源
    最近更新 更多