r - data.table 相当于 dplyr::filter_at

标签 r dplyr data.table

考虑数据:

library(data.table)
library(magrittr)

vec1 <- c("Iron", "Copper")

vec2 <- c("Defective", "Passed", "Error")

set.seed(123)
a1 <- sample(x = vec1, size = 20, replace = T)
b1 <- sample(x = vec2, size = 20, replace = T)

set.seed(1234)
a2 <- sample(x = vec1, size = 20, replace = T)
b2 <- sample(x = vec2, size = 20, replace = T)

DT <- data.table(
  c(1:20), a1, b1, a2, b2
) %>% .[order(V1)]

names(DT) <- c("id", "prod_name_1", "test_1", "prod_name_2", "test_2")

我需要过滤 test_1test_2 值为“通过” 的行。因此,如果这些列都没有指定的值,则删除该行。通过dplyr,我们可以使用filter_at()动词:

> # dplyr solution...
> 
> cols <- grep(x = names(DT), pattern = "test", value = T, ignore.case = T)
> 
> 
> DT %>% 
+   dplyr::filter_at(.vars = grep(x = names(DT), pattern = "test", value = T, ignore.case = T), 
+                    dplyr::any_vars(. == "Passed")) -> DT.2
> 
> DT.2
  id prod_name_1 test_1 prod_name_2    test_2
1  3        Iron Passed      Copper Defective
2  5      Copper Passed      Copper Defective
3  7      Copper Passed        Iron    Passed
4  8      Copper Passed        Iron     Error
5 11      Copper  Error      Copper    Passed
6 14      Copper  Error      Copper    Passed
7 16      Copper Passed      Copper     Error

酷。在 data.table 中是否有类似的方法来执行此操作?

这是我得到的最接近的:

> lapply(seq_along(cols), function(x){
+   
+   setkeyv(DT, cols[[x]])
+   
+   DT["Passed"]
+   
+ }) %>% 
+   do.call(rbind,.) %>% 
+   unique -> DT.3
> 
> DT.3
   id prod_name_1 test_1 prod_name_2    test_2
1:  3        Iron Passed      Copper Defective
2:  5      Copper Passed      Copper Defective
3:  8      Copper Passed        Iron     Error
4: 16      Copper Passed      Copper     Error
5:  7      Copper Passed        Iron    Passed
6: 11      Copper  Error      Copper    Passed
7: 14      Copper  Error      Copper    Passed
> 
> identical(data.table(DT.2)[order(id)], DT.3[order(id)])
[1] TRUE

你们有更优雅的解决方案吗?最好是包含在诸如 dplyr::filter_at() 之类的动词中的内容。

最佳答案

我们可以在.SDcols中指定'cols',循环遍历Data.table的子集(.SD)来比较该值是否“通过”,使用 | 将其减少为单个向量,并对行进行子集化

res2 <- DT[DT[,  Reduce(`|`, lapply(.SD, `==`, "Passed")), .SDcols = cols]]

与OP帖子中的dplyr输出进行比较

identical(as.data.table(res1), res2)
#[1] TRUE

关于r - data.table 相当于 dplyr::filter_at,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48668509/

相关文章:

r - dbplyr copy_to 不将表保存到数据库

r - 加速 R 计算的操作

r - 向量化 data.table 之类的、grepl 或类似的以进行大数据字符串比较

r - 使用 dplyr 中的 group_by 函数来操作 data.frame 对象集

python - 无法通过 python 中的公司代理将正确的凭据传递到服务器,但可以在 R 中执行此操作

r - 变异 : chose all rows except the current one in a grouped df (dplyr)

r - 计算小于 x 的值并通过多个组找到最接近 x 的值

r - 提高 xts 的多个时间范围子集的性能?

r - 选择某些元素以逐步构建 ioslides

r - ggplot2根据数据值填充颜色