如何根据函数中传递的参数对data.table对象进行子集化?

时间:2018-06-03 09:13:58

标签: r data.table

我无法弄清楚如何在函数中对R中的data.table进行子集化。我的代码如下,并使用虹膜数据集来简化。我的目标是遍历数据集,并在每个子组中执行许多不同的功能,并将所有结果值存储在表示该子组的单个数据集中。任何帮助表示赞赏。谢谢!

  fx <- function(data, col_var){
  for(i in 0:nrow(distinct(data[,..col_var]))){
    if(i == 0){
      # do one thing
    }
    else if(i > 0){
      group <- data %>% distinct('col_var')
      group_dt <- data['col_var' == group[1],]
      print(group_dt)
    }
  }
}

library('tidyverse')
library('data.table')
data(iris)
data <- data.table(iris)
fx(data, 'Species')

不幸的是,到目前为止我所做的所有工作都会导致没有行的数据子集,或者出现如下所示的错误消息:

Error in `[.data.table`(data, "col_var" == group[1], ) : 
i is invalid type (matrix). Perhaps in future a 2 column matrix could return a list of elements of DT (in the spirit of A[B] in FAQ 2.14). Please let datatable-help know if you'd like this, or add your comments to FR #657.

1 个答案:

答案 0 :(得分:1)

data.table way

在大多数情况下,您可以在data.table内执行所有操作,而无需任何迭代控件(forlapply

dt <- data.table(iris)
group.by.name <- "Species"
res <- dt[, .(count = .N), by = group.by.name]

split-transform-rbind策略:

如果你需要对data.table进行复杂的转换,你可以像这样拆分转换rbind数据:

library('data.table')
dt <- data.table(iris)
group.by.name <- "Species"
res <- lapply(split(dt, by = group.by.name), function(data) {
  data[, .(count = .N)]
})
res <- rbindlist(res, idcol = group.by.name)

你有可读性和速度之间的交易。 使用mcapply,您可能会在更大的实例上获得速度。

通常,您可以将复杂的逻辑移动到矢量函数中,并以不可读的方式执行data.table方式。