在R中使用data.table进行交叉表分析

11

我喜欢R中的data.table包,我认为它可以帮助我执行复杂的交叉制表任务,但我还没有弄清如何使用该包来执行类似于table的任务。

以下是一些复制调查数据:

opinion <- c("gov", "market", "gov", "gov")
ID <- c("resp1", "resp2", "resp3", "resp4")
party <- c("GOP", "GOP", "democrat", "GOP")

df <- data.frame(ID, opinion, party)

在表格中,按政党统计意见数量就像是 table(df$opinion, df$party) 这样简单。

我已经在data.table中完成了类似的操作,但结果很笨拙,而且会添加一个独立的列。

dt <- data.table(df)
dt[, .N, by="party"]

data.table中有许多分组操作可用于快速和复杂的调查数据交叉表,但我没有找到任何关于如何使用它的教程。感谢任何帮助。

1个回答

14

我们可以使用data.table中的dcast函数(请参见项目wiki上的Efficient reshaping using data.tables章节或CRAN项目页面)。

dcast(dt, opinion~party, value.var='ID', length)

基准测试

如果我们使用稍大的数据集,并比较使用reshape2data.table中的dcast函数的速度。

set.seed(24)
df <- data.frame(ID=1:1e6, opinion=sample(letters, 1e6, replace=TRUE),
  party= sample(1:9, 1e6, replace=TRUE))
system.time(dcast(df, opinion ~ party, value.var='ID', length))
#   user  system elapsed 
#  0.278   0.013   0.293 
system.time(dcast(setDT(df), opinion ~ party, value.var='ID', length))
#   user  system elapsed 
# 0.022   0.000   0.023 

system.time(setDT(df)[, .N, by = .(opinion, party)])
#  user  system elapsed 
# 0.018   0.001   0.018 

第三个选择稍微好一些,但它是以“长”格式呈现的。如果OP想要“宽”格式,则可以使用data.table dcast

注意:我正在使用开发版本即v1.9.7,但CRAN应该足够快。


6
@tom 不是将其视为 data.framedcast 是来自于 data.table 软件包而非 reshape2,针对速度进行了优化。 - akrun
@tom 已更新并附上了基准测试结果。 - akrun
@akrun 你在使用1.9.7版本吗?我想知道你是否从FR #1251的解决方案中获得了性能提升(如果我理解正确的话,这个解决方案不在当前的CRAN发布版本1.9.6中);如果是的话,应该要提到这一点。我记得dt[,table(x,y)]dt[,.N,by=.(x,y)]之间的竞争性已经不再存在于更新后的版本中。 - MichaelChirico
@akrun 我认为是这样,但 dt[,table(x,y)] 是另一个简单的选项(在我的机器上比 reshape2::dcast 更快,但比 data.table::dcast 慢)。 - MichaelChirico
@MichaelChirico 这样做会更节省内存吗? - akrun
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接