【问题标题】:How to use or/and in dplyr to subset a data.frame如何在 dplyr 中使用或/和对 data.frame 进行子集化
【发布时间】:2014-08-10 18:25:18
【问题描述】:

我想用 or/and 的组合对 data.frame 进行子集化。这是我使用普通 R 函数的代码。

df <- expand.grid(list(A = seq(1, 5), B = seq(1, 5), C = seq(1, 5)))
df$value <- seq(1, nrow(df))

df[(df$A == 1 & df$B == 3) |
    (df$A == 3 & df$B == 2),]

如何使用 dplyr 包中的过滤器功能转换它们?感谢您的任何建议。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    dplyr解决方案:

    加载库:

    library(dplyr)

    过滤条件如上:

    df %&gt;% filter(A == 1 &amp; B == 3 | A == 3 &amp; B ==2)

    【讨论】:

      【解决方案2】:

      您也可以使用subset()[。以下是一些不同的方法及其在更大数据集上的各自基准。

      df <- expand.grid(A = 1:100, B = 1:100, C = 1:100)
      df$value <- 1:nrow(df)
      
      library(dplyr); library(microbenchmark)
      f1 <- function() subset(df, A == 1 & B == 3 | A == 3 & B == 2)
      f2 <- function() filter(df, A == 1 & B == 3 | A == 3 & B == 2)
      f3 <- function() df[with(df, A == 1 & B == 3 | A == 3 & B == 2), ]
      f4 <- function() df[(df$A == 1 & df$B == 3) | (df$A == 3 & df$B == 2),]
      
      microbenchmark(subset = f1(), filter = f2(), with = f3(), "$" = f4())
      # Unit: milliseconds
      #    expr      min       lq     mean   median       uq      max neval
      #  subset 47.42671 49.99802 75.95385 92.24430 96.05960 141.2964   100
      #  filter 36.94019 38.77325 60.22831 42.64112 84.35896 155.0145   100
      #    with 38.90918 44.36299 71.29214 86.39629 88.89008 134.7670   100
      #       $ 40.22723 44.08606 71.32186 86.71372 89.59275 133.1132   100
      

      【讨论】:

      • 有趣,我不知道with()$ 之间有这样的区别。
      • 我使用 filter() 的结果越来越差:Unit: microseconds expr median f1() 511.0195 f2() 1725.4910 f3() 362.2040 f4() 489.8515 R: 3.1.1 dplyr 0.3.0.2
      • @docendodiscimus - 没有。这是一个糟糕的基准;)已编辑
      • neval = 100 还不够。我已经对更大的数据集(5k 行)和neval = 1000 进行了多次测试,但不同意说subsetfilter[ 之间哪个更快。
      【解决方案3】:

      有趣。我试图查看结果数据集方面的差异,但我无法解释为什么旧的“[”运算符表现不同:

      # Subset for year=2013
      sub<-brfss2013 %>% filter(iyear == "2013")
      dim(sub)
      #[1] 486088    330
      length(which(is.na(sub$iyear))==T)
      #[1] 0
      
      sub2<-filter(brfss2013, iyear == "2013")
      dim(sub2)
      #[1] 486088    330
      length(which(is.na(sub2$iyear))==T)
      #[1] 0
      
      sub3<-brfss2013[brfss2013$iyear=="2013", ]
      dim(sub3)
      #[1] 486093    330
      length(which(is.na(sub3$iyear))==T)
      #[1] 5
      
      sub4<-subset(brfss2013, iyear=="2013")
      dim(sub4)
      #[1] 486088    330
      length(which(is.na(sub4$iyear))==T)
      #[1] 0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-25
        • 1970-01-01
        • 2011-10-19
        • 2020-06-28
        相关资源
        最近更新 更多