【问题标题】:Translating filter_all(any vars()) to base R将 filter_all(any vars()) 翻译成 base R
【发布时间】:2022-11-17 06:34:33
【问题描述】:

我有一个包含各种数字的数据框。我想要的是使用所有列值对行进行子集化。

可以使用 dplyr 编写以下代码:

library(dplyr)

set.seed(1)

df <- data.frame (matrix (round (runif(500, 0, 1), digits = 1), 10, 5))

dfn <- df |> dplyr::filter_all (dplyr::any_vars (grepl (0.5,.))) 

有谁知道这段代码的基本 R 版本是什么?很感谢任何形式的帮助。

【问题讨论】:

    标签: r


    【解决方案1】:

    1)对列应用 grepl,然后获取总和为正的那些行:

    df[rowSums(sapply(df, grepl, pattern = 0.5)) > 0, ]
    

    2)一种变体是使用 lapply 而不是 sapply 和 do.call/pmax 而不是 rowSums:

    df[do.call("pmax", lapply(df, grepl, pattern = 0.5)) > 0, ]
    

    3)第三种方法可以从 max.col 中得到

    s <- sapply(df, grepl, pattern = 0.5)
    df[s[cbind(1:nrow(s), max.col(s))], ]
    

    4)减少 |可以使用

    df[Reduce(`|`, lapply(df, grepl, pattern = 0.5)), ]
    

    基准

    下面我们比较各种解决方案的速度。 p0 是问题的解决方案,是最慢的。其余的根据重要性没有不同,尽管上面的 (2) 或 (4) 根据使用的指标给出了最低的运行时间。

    library(microbenchmark)
    
    microbenchmark(
    P0 = df |> dplyr::filter_all (dplyr::any_vars (grepl (0.5,.))),
    p1 = df[rowSums(sapply(df, grepl, pattern = 0.5)) > 0, ],
    p2 = df[do.call("pmax", lapply(df, grepl, pattern = 0.5)) > 0, ],
    p3 = { s <- sapply(df, grepl, pattern = 0.5)
           df[s[cbind(1:nrow(s), max.col(s))], ]},
    p4 = df[Reduce(`|`, lapply(df, grepl, pattern = 0.5)), ],
    p5 = { has_0.5 <- apply(df, 1, function(x) any(grepl(0.5, x)))
            df[has_0.5, ]}
    )
    

    给予

    Unit: microseconds
     expr      min       lq       mean   median        uq      max neval cld
       P0 140597.8 142671.0 173710.712 151614.6 173295.00 487564.7   100   b
       p1    544.4    572.3   1838.821    593.8    623.15 117795.9   100  a 
       p2    485.3    502.2    946.143    514.8    567.15  34891.1   100  a 
       p3    607.9    631.6    766.101    655.6    719.10   3177.0   100  a 
       p4    454.6    473.8    592.819    486.0    538.30   1518.8   100  a 
       p5    945.9    980.4   1344.161   1013.2   1107.80  23137.1   100  a 
    

    【讨论】:

      【解决方案2】:

      一种可能性:

      has_0.5 <- apply(df, 1, function(x) any(grepl(0.5, x)))
      df[has_0.5, ]
      

      【讨论】:

      • 谢谢大家,非常感谢您的帮助!
      猜你喜欢
      • 2020-08-11
      • 2015-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-09
      • 2019-09-25
      • 2016-11-18
      • 2021-11-22
      相关资源
      最近更新 更多