【问题标题】:R compare column values row wiseR逐行比较列值
【发布时间】:2020-07-10 21:15:37
【问题描述】:

我有一个具有以下结构的数据框,我想创建一个附加列,根据某些标准逐行比较所有列值,即 M==1 和所有其他列 == 0

如何使用 dplyr 或其他方式编写代码以在大型数据集上逐行执行此类操作?

      M     B     L     H
  <dbl> <dbl> <dbl> <dbl>
1     1     0     0     0
2     0     1     0     0
3     1     0     0     0
4     0     1     0     0
5     0     0     1     0
6     0     0     0     1

【问题讨论】:

    标签: r dplyr tidyverse


    【解决方案1】:

    这是在其余列上使用map/reduce 的一个选项,以检查它们是否全部为0,然后使用M == 1 执行&amp;

    library(dplyr)# 1.0.0
    library(purrr)
    df1 %>%
         mutate(flag = M == 1 & select(., -M) %>% 
                                  map(., `==`, 0) %>%
                                  reduce(`&`))
    #  M B L H  flag
    #1 1 0 0 0  TRUE
    #2 0 1 0 0 FALSE
    #3 1 0 0 0  TRUE
    #4 0 1 0 0 FALSE
    #5 0 0 1 0 FALSE
    #6 0 0 0 1 FALSE
    

    另一个选项是rowwisec_across(来自dplyr &gt;= 1.0)(但它可能会更慢)

    df1 %>%
        rowwise %>% 
        mutate(new = all(c_across(B:H) == 0) & M == 1)
    # A tibble: 6 x 5
    # Rowwise: 
    #      M     B     L     H new  
    #  <int> <int> <int> <int> <lgl>
    #1     1     0     0     0 TRUE 
    #2     0     1     0     0 FALSE
    #3     1     0     0     0 TRUE 
    #4     0     1     0     0 FALSE
    #5     0     0     1     0 FALSE
    #6     0     0     0     1 FALSE
    

    map/reduce 类似于带有lapply/Reducebase R 选项,其中我们使用lapply 循环数据集的列(这里是df1[-1],因为我们不想使用第一列,即'M' ),用==创建逻辑vectors的list

    lapply(df1[-1], `==`, 0)
    #$B
    #[1]  TRUE FALSE  TRUE FALSE  TRUE  TRUE
    
    #$L
    #[1]  TRUE  TRUE  TRUE  TRUE FALSE  TRUE
    
    #$H
    #[1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE
    

    然后将Reduce list 通过比较相应的list 元素位置,将list&amp; 相比较,即如果它们都是TRUE,则返回TRUE

    Reduce(`&`, lapply(df1[-1], `==`, 0))
    #[1]  TRUE FALSE  TRUE FALSE FALSE FALSE
    

    然后追加M == 0

    df1$M == 0 & Reduce(`&`, lapply(df1[-1], `==`, 0))
    

    或者base R 中的另一个选项是rowSums

    df1$M == 1 & !rowSums(df1[-1] != 0)
    

    也可以写成

    df1$M == 1 & rowSums(df1[-1] == 0) == ncol(df1[-1])
    

    数据

    df1 <- structure(list(M = c(1L, 0L, 1L, 0L, 0L, 0L), B = c(0L, 1L, 0L, 
    1L, 0L, 0L), L = c(0L, 0L, 0L, 0L, 1L, 0L), H = c(0L, 0L, 0L, 
    0L, 0L, 1L)), class = "data.frame", row.names = c("1", "2", "3", 
    "4", "5", "6"))
    

    【讨论】:

    • 这个很好用,谢谢!您能否解释一下 map 和 reduce 函数是如何工作的,以便我了解如何在此基础上进行构建?
    • @ErikRasmussen 添加了一些解释。希望对你有帮助
    猜你喜欢
    • 2021-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    相关资源
    最近更新 更多