【问题标题】:How to filter out rows that have same number for all columns?如何过滤掉所有列具有相同编号的行?
【发布时间】:2017-10-30 19:43:06
【问题描述】:

我想过滤掉数据框中在同一行的所有列中具有相同数据的行?在这个例子中,我想识别user_id13。我该怎么做?

df <- read_csv("user_id, q1, q2, q3, q4
1, 5, 5, 5, 5
2, 4, 3, 5 ,6
3, 2, 2, 2, 2
4, 5, 4, NA, 4")

目的:识别在问卷中的所有问题上打勾的人。

更新:建议的解决方案工作正常,直到 q1 有 NA。

df <- read_csv("user_id, q1, q2, q3, q4
               1, 5, 5, 5, 5
               2, NA, 3, 5 ,6
               3, 2, 2, 2, 2
               4, 5, 4, NA, 4")

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    您可以选择其中一个问题,例如q1,并与其他问题进行比较,选择是否所有问题都相等;

    df$user_id[rowSums(df$q1 != df[-1], na.rm=T) == 0]
    # [1] 1 3
    

    df %>% filter(rowSums(.[-1] != q1, na.rm=T) == 0)
    
    # A tibble: 2 x 5
    #  user_id    q1    q2    q3    q4
    #    <int> <int> <int> <int> <int>
    #1       1     5     5     5     5
    #2       3     2     2     2     2
    
    • q1 列与其他qs 列与.[-1] != q1 进行比较,这里.df 来自%&gt;%.[-1] 删除user_id 列;
    • 通过忽略 NA 执行 rowSums(.[-1] != q1, na.rm=T) 检查有多少列不等于 q1
    • 如果没有一个列不等于q1,则所有qs 列的编号都相同,根据它进行过滤;

    【讨论】:

    • 非常感谢,Psidom。看起来第二种方法是我需要的。你能解释一下代码吗?我对 R 很陌生。
    • 更新了一些解释~
    • @Tyn,如果你只是做df[rowSums(df$q1 != df[-1], na.rm=T) == 0,],你也可以使用第一个
    • q1 为 NA 时解决方案有小问题 :-( 试试看能不能解决
    • 好的,如果我必须删除 na.rm 位才能得到 1 是 NA 的情况。我还删除了所有问题都是 NA 的行。将在问题中更新此内容。
    【解决方案2】:

    除非您的 data.frame 很大,否则您可以在行上使用 apply (MARGIN = 1)

    df$user_id[apply(X = df[,-1], MARGIN = 1, FUN = function(x) length(unique(x)) == 1)]
    #[1] 1 3
    
    df[apply(X = df[,-1], MARGIN = 1, FUN = function(x) length(unique(x)) == 1),]
    #  user_id q1 q2 q3 q4
    #1       1  5  5  5  5
    #3       3  2  2  2  2
    

    df$user_id[Reduce(function(x, y) pmax(x, y, na.rm = TRUE), df[,-1]) ==
                   Reduce(function(x, y) pmin(x, y, na.rm = TRUE), df[,-1])]
    #[1] 1 3
    

    【讨论】:

    • 谢谢 d.b.我还没有学过函数,所以我会记住这一点。
    【解决方案3】:

    你可以用一些基本的 R 代码来解决它。

    # Generate your data set
    df <- data.frame(user_id =c(1,2,3,4),
                     q1 = c(5,4,2,5),
                     q2 = c(5,3,2,4),
                     q3 = c(5,5,2, NA),
                     q4 = c(5,6,2,4))
    
    # populate the vector with a loop
    test <- character(0)
    for(i in 1:nrow(df)){
    # check if the sum of the values is equal to the sum of the last value 
    # repeated. This can only be true if all values are the same
      if(sum(df[i,2:5], na.rm = TRUE) - sum(rep(df[i,5],4)) == 0){
        test[i] <- "equal"
      } else{
        test[i] <- "not_equal"
      }
    
    }
    
    # finally attach the vector as a column to your data frame
    df$test <- test
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-18
      • 2018-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多