【问题标题】:Extracting levels from data.table从 data.table 中提取级别
【发布时间】:2015-11-12 00:44:05
【问题描述】:

对于从 data.table 中提取级别,标准方法是将data.table 作为列表覆盖还是以某种方式在括号内进行?

例如,使用 npk 内置数据,我知道前 4 列是因子,我想提取水平。

dat <- as.data.table(npk)

这就是我想要的,关卡列表

levs <- lapply(dat[,1:4,with=FALSE], levels)

但是,我是否错过了类似这样的 data.table 方式? (这是不对的,因为它会重复关卡以匹配最长的关卡)。

levs2 <- dat[, lapply(.SD, levels), .SDcols=names(dat)[1:4]]

ps。抱歉,如果这看起来很愚蠢,我只是想学习正确的 data.table 习语。

【问题讨论】:

  • dat[, .(Var=names(.SD), levs=lapply(.SD,levels)), .SDcols=names(dat)[1:4] ] 如果你想得到一些复杂的data.table 输出。

标签: r data.table


【解决方案1】:

你的第一个例子对我来说似乎是合理的,我认为你不能在 data.table 的括号内做,因为返回类型应该是一个列表。

另一个选项是Filter(Negate(is.null),lapply(DT,levels)),它的额外好处是不需要事先知道哪些列是因子

【讨论】:

  • @rawr 公平点,但我宁愿计算机这样做,然后自己手动检查列表。无法想象成本如此之大。 levels 函数是先测试向量类型,然后再哭NULL,还是测试向量的每个元素。或者说,行数越多,成本会增加吗?
  • 行还是列? levels 甚至不看行,只看属性。我不使用数据表,但我认为索引作为因子的列然后假设数据表也通过引用进行列子集化来获取级别会更有效。基本上 lapply 是缓慢的位
  • @rawr 我的意思是行。你是对的(用testa &lt;- runif(100000000);testb &lt;- runif(2);microbenchmark::microbenchmark(a = levels(testa), b = levels(testb)) 证明)这意味着成本只与列而不是行成比例。因此,我宁愿使用通用解决方案测试所有列,然后必须手动识别每一列(这是一个人为问题,也会随着列数的增加而变化)。
  • lapply(Filter(is.factor,DT), levels) 这样的东西对我来说更直观,也许更通用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-26
  • 2021-06-17
  • 1970-01-01
  • 2021-06-14
  • 1970-01-01
  • 2013-01-16
  • 2021-08-26
相关资源
最近更新 更多