【问题标题】:Reshaping data using the data.table package使用 data.table 包重塑数据
【发布时间】:2013-08-24 00:53:45
【问题描述】:

几天前我也问过同样的问题 ( click here),但没有提到使用 data.table 的结果将不胜感激

“聚合解决方案”工作正常,即使它很慢!我正在寻找一种更快的方法来解决这个问题。

我想重塑以下data.frame:

df <- data.frame(x=c("p1","p1","p2"),y=c("a","b","a"),z=c(14,14,16))
df
   x y  z
1 p1 a 14
2 p1 b 14
3 p2 a 16

让它看起来像这样:

df2 <- data.frame(x=c("p1","p2"),a=c(1,1),b=c(1,0),z=c(14,16))
   x a b  z
1 p1 1 1 14
2 p2 1 0 16

df 中的变量 y 应该被破坏,以便它的元素是新变量,每个都是虚拟编码的。所有其他变量(在这种情况下只是 z)对于每个人都是相等的(p1,p2 等)。特定人 p 具有不同值的唯一变量是 y
我想要这个的原因是因为我需要通过变量x 将此数据集与其他数据集合并。问题是,每人需要一行(p1p2 等)。

【问题讨论】:

  • 我应该这样做,但是当我发布这个问题时,我只是没有考虑“自包含方面”。因为 eddi 已经发布了一种方式,我想我会保持原样。不过,感谢您的评论

标签: r data.table


【解决方案1】:

目前在data.table 中使用宽格式有点尴尬,但我认为这可行:

library(data.table)
dt = data.table(x=c("p1","p1","p2"),y=c("a","b","a"),z=c(14,14,16))

setkey(dt, x, y)
dt[CJ(unique(x), unique(y)), list(.N, z)][,
   setNames(as.list(c(N, z[!is.na(z)][1])), c(y, 'z')), by = x]
#    x a b  z
#1: p1 1 1 14
#2: p2 1 0 16

CJ 部分通过唯一 xy 的所有组合连接,然后在该连接中有一个隐藏的 by-without-by 用于通过 @ 计算计数987654326@。一旦你有了这些,只需将它们水平放置在每个x 以及任何非NA z (我选择第一个),这是使用as.list 完成的。最后setNames 正确设置了列名。

【讨论】:

  • @beginneR 解释添加
  • 谢谢,这太棒了!但现在它变得更加复杂。如果有另一个变量像 y,例如 z。其中值也可能不同。是否有可能针对这种情况调整代码。 thelatemail 使用聚合编辑了我在此处链接的问题的第一个答案,用于两列以上。如果您的 data.table 解决方案也可以这样做,那将是完美的。另请参阅我的 cmets 在链接问题中对“他”的回答。 (PS:抱歉链接到另一个问题)
  • @beginneR 从我可以看到另一个问题中的两个变量案例只是上述算法的两次单独运行 - 只需将密钥设置为 xy 首先,然后 @987654333 @ 和z,对每种情况执行上述操作,然后cbind 结果
  • hmm 我收到以下错误消息:“j 不会为每个组计算相同数量的列”。但是这个错误与 cbind() 无关。当我只为单个变量尝试您的答案代码时。不明白为什么这对我的数据不起作用。你有什么想法吗?
  • @beginneR 该错误意味着j-expressions 为您的by 参数的不同值产生不同大小的结果 - 尝试查明两个冲突的by 值,然后您可能能够弄清楚如何修复它;一种确定方法是在您的j-expression 中添加一个print 语句,您将能够看到它在哪里中断
猜你喜欢
  • 2017-11-04
  • 2019-01-10
  • 2018-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-05
  • 2019-02-28
  • 2016-08-28
相关资源
最近更新 更多