数到 data.table 后完成所有组合

Complete with all combinations after counting on data.table

我的数据中有些列作为因子,有些列作为字符。我想计算所有组合并用 data.table 语法编写一个函数

# Load libraries

library(dplyr)
library(data.table)

# Create data

i_df = iris %>%
  filter(Species != 'virginica') %>%
  mutate(
    len   = ifelse(Sepal.Length > 6, 'large', 'tiny'),
    width = ifelse(Sepal.Width > 3, 'thick', 'thin'),
    color = ifelse(Species == 'setosa', 'green', 'red')
  ) %>% 
  mutate(
    len   = factor(len, levels = c('large', 'med_len', 'tiny')),
    width = factor(width, levels = c('thick', 'med_width', 'thin'))
  )

这将是我的函数的一个例子:

myfun = function(d, g, mode) {
  
  # Convert to data.table  
  setDT(d)
  
  # Counting
  res = d[, .N, by = g]
  
  # Complete combinations
  setkeyv(res, cols = g)
  
  res = switch(
    mode,
    manual = {
      res[CJ(levels(d$Species), levels(d$len), levels(d$width), unique(d$color)),]
    },
    auto = {
      m = res[, do.call(CJ, c(.SD, unique = TRUE)), .SDcols = g]
      res[m, on = g]
    }
  )
  
  # Add zero when NA
  res[is.na(res)] = 0
  
  # Return
  return(res)
  
}

如何运行:

g_tmp = c('Species', 'len', 'width', 'color')

myfun(d = i_df, g = g_tmp, mode = 'manual')
myfun(d = i_df, g = g_tmp, mode = 'auto')

如您所见,我使用的是 setkeyv 而不是 setkey,因为我需要使用字符向量 g。但是当 CJ 完成后,我无法使用字符向量输入 mode = 'auto'。在那里,指示所有因素的所有因素水平和所有字符列的所有当前颜色 unique。如您所见,使用 mode = 'manual',返回 54 行,使用 mode = 'auto',不返回不存在的因子水平,结果为 16 行。

我找到了 and ,但是当我混合使用因子和字符列时我无法使用它

由于一些列是一些不存在水平的因素,unique在这里不好,只针对字符列

这是解决您的问题的一种可能方法。请注意,data.table 上下文中的参数 with=FALSE 允许使用标准 data.frame 规则 select 列。在下面的示例中,我假设用于计算所有组合的列作为 character 向量传递给 myfun。 请记住,数据集中的任何列都不应命名为 gcases.EACHI in by 允许对 i 中的每一行执行一些操作。

myfun = function(d, g) {
  # get levels (for factors) and unique values for other types. 
  fn <- function(x) if(is.factor(x)) levels(x) else unique(x)
  gcases <- lapply(setDT(d, key=g)[, g, with=FALSE], fn)
  
  # count based on all combinations
  d[do.call(CJ, gcases), .N, keyby=.EACHI]
}