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