data.table-通过比较列列表和值列表进行选择

时间:2019-05-22 18:51:13

标签: r data.table

我正在尝试编写一个函数,该函数需要一个data.table,一个列列表和一个值列表,并选择行,以使每个列都被相应的值过滤。

因此,考虑以下data.table

> set.seed(1)
> dt = data.table(sample(1:5, 10, replace = TRUE),
                  sample(1:5, 10, replace = TRUE),
                  sample(1:5, 10, replace = TRUE))
> dt
    V1 V2 V3
 1:  1  5  5
 2:  4  5  2
 3:  1  2  2
 4:  2  2  1
 5:  5  1  4
 6:  3  5  1
 7:  2  5  4
 8:  3  1  3
 9:  3  1  2
10:  1  5  2

调用filterDT(dt, c(V1, V3), c(1, 2))将选择V1 = 1V3 = 2(上面的第3行和第10行)所在的行。

我最好的想法是使用.SD.SDcols代表所需的列,然后在i中进行比较(来自dt[i,j,by]):

> filterDT <- function(dt, columns, values) {
      dt[.SD == values, , .SDcols = columns]
  }
> filterDT(dt, c("V1", "V3"), c(1, 2))
Empty data.table (0 rows and 3 cols): V1,V2,V3

不幸的是,即使仅按一列进行过滤,这也不起作用。

我注意到.SD的所有示例都在j中在线使用,这表明我可能做错了。

有什么建议吗?

2 个答案:

答案 0 :(得分:4)

假设要filter的“值”是与所选“列”相对应的值,我们可以与MapReduce和{{1}进行比较}

&

作为功能

dt[dt[ , Reduce(`&`, Map(`==`, .SD, values)) , .SDcols = columns]]

或者另一个选择是filterDT <- function(dt, columns, values) { dt[dt[ , Reduce(`&`, Map(`==`, .SD, values)) , .SDcols = columns]] } filterDT(dt, c("V1", "V3"), c(1, 2)) # V1 V2 V3 #1: 1 4 2

setkey

答案 1 :(得分:4)

我认为您应该能够编写使用任意数量的列进行连接的函数:

public class FeedbackBody{
    private final String email;
    private final String feedback;

    public FeedbackBody(String email, String feedback){
        this.email = email;
        this.feedback = feedback;
    }
}

基本上,该函数从提供给#' Filter a data.table on an arbitrary number of columns #' #' @param dt data.table to filter #' @param ... named columns to filter on and their values filter_dt <- function(dt, ...) { filter_criteria <- as.data.table(list(...)) dt[filter_criteria, on = names(filter_criteria), nomatch=0] } # A few examples: filter_dt(dt, V1=1, V3=2) filter_dt(dt, V1=2, V2=2, V3=5) filter_dt(dt, V1=c(5,4,4), V3=c(1,2,5)) 的参数构造一个新的data.table,每个参数成为新data.table ...中的一列。然后将其提供给filter_criteria的{​​{1}}参数,并将列名i用作联接中的列。