【问题标题】:R subsetting rows where values in multiple columns don't matchR子集多列中的值不匹配的行
【发布时间】:2016-11-08 19:06:07
【问题描述】:

抱歉,如果已经有人问过这个问题,但我搜索并找不到我正在尝试做的确切示例。我正在尝试对数据框进行子集化,以排除在五列中具有匹配数值的行。例如,对于以下数据帧 df,我想返回一个仅包含 1:2、5:6 和 8:10 行的新数据帧:

Row A   B   C   D   E
1   1   1   2   3   1
2   4   1   2   3   5
3   2   2   2   2   2
4   5   5   5   5   5
5   4   4   2   3   4
6   2   1   3   5   2
7   3   3   3   3   3
8   3   2   5   3   3
9   2   1   2   2   4
10  3   3   3   2   3

我无法弄清楚如何为超过两列执行此操作。我尝试了以下方法并知道它们不正确。

df2 <- df[!duplicated(df, c("A", "B", "C", "D", "E"))]

df2 <- df[df$A==df$B==df$C==df$D==df$E,]

提前致谢。

【问题讨论】:

    标签: r


    【解决方案1】:

    数据框通常按列而不是按行操作,这就是您的 duplicated 尝试不起作用的原因。 (它正在检查这些列中的重复行。)您的== 不起作用,因为== 是二元运算符,df$A == df$B 将是 TRUE 或 FALSE,然后 (df$A == df$B) == df$C(隐含括号)将进行测试如果df$C 为真或假。

    apply 是在每个 上运行函数的好方法。它会将您的数据框转换为矩阵以运行该函数,但在这种情况下,A 到 E 列都是数字。这是一种方法:

    df[apply(df[, -1], 1, function(x) length(unique(x))) > 1, ]
    #    Row A B C D E
    # 1    1 1 1 2 3 1
    # 2    2 4 1 2 3 5
    # 5    5 4 4 2 3 4
    # 6    6 2 1 3 5 2
    # 8    8 3 2 5 3 3
    # 9    9 2 1 2 2 4
    # 10  10 3 3 3 2 3
    

    您可以为apply 提供各种不同的功能来测试所有元素是否相同。

    我假设您实际上有一个名为 Row 的列。如果不是这种情况,请在我上面的代码中省略-1


    使用此数据,与dput() 重复共享。

    df = structure(list(Row = 1:10, A = c(1L, 4L, 2L, 5L, 4L, 2L, 3L, 
    3L, 2L, 3L), B = c(1L, 1L, 2L, 5L, 4L, 1L, 3L, 2L, 1L, 3L), C = c(2L, 
    2L, 2L, 5L, 2L, 3L, 3L, 5L, 2L, 3L), D = c(3L, 3L, 2L, 5L, 3L, 
    5L, 3L, 3L, 2L, 2L), E = c(1L, 5L, 2L, 5L, 4L, 2L, 3L, 3L, 4L, 
    3L)), .Names = c("Row", "A", "B", "C", "D", "E"), class = "data.frame", row.names = c(NA, 
    -10L))
    

    【讨论】:

    • 谢谢!这正是我所需要的。
    【解决方案2】:

    您可以简单地将所有列与单个列进行比较,看看是否都相同

    df[rowSums(df[-1] == df[, 1]) < (ncol(df) - 1), ]
    #    A B C D E
    # 1  1 1 2 3 1
    # 2  4 1 2 3 5
    # 5  4 4 2 3 4
    # 6  2 1 3 5 2
    # 8  3 2 5 3 3
    # 9  2 1 2 2 4
    # 10 3 3 3 2 3
    

    或者只是df[rowSums(df == df[, 1]) &lt; (ncol(df)), ]


    或者类似地,您可以同时避免矩阵转换并将Reducelapply 组合在一起

    df[!Reduce("&" , lapply(df, `==`, df[, 1])), ]
    #    A B C D E
    # 1  1 1 2 3 1
    # 2  4 1 2 3 5
    # 5  4 4 2 3 4
    # 6  2 1 3 5 2
    # 8  3 2 5 3 3
    # 9  2 1 2 2 4
    # 10 3 3 3 2 3 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-18
      • 2015-09-16
      • 1970-01-01
      • 1970-01-01
      • 2015-07-18
      • 2017-12-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多