【问题标题】:Reshape long structured data.table into a wide structure using data.table functionality?使用 data.table 功能将长结构化 data.table 重塑为宽结构?
【发布时间】:2013-08-05 13:05:53
【问题描述】:
> library(data.table)
> A <- data.table(x = c(1,1,2,2), y = c(1,2,1,2), v = c(0.1,0.2,0.3,0.4))
> A
   x y   v
1: 1 1 0.1
2: 1 2 0.2
3: 2 1 0.3
4: 2 2 0.4
> B <- dcast(A, x~y)
Using v as value column: use value.var to override.
> B
  x   1   2
1 1 0.1 0.2
2 2 0.3 0.4

显然,我可以使用 f.x 将 data.table 从长到宽重塑。包 reshape2 的 dcast。但是 data.table 带有一个重载的括号运算符,提供像“by”和“group”这样的参数,这让我想知道是否可以使用它来实现它(到 data.table 特定功能)?

手册中的一个随机示例:

DT[,lapply(.SD,sum),by=x]

这看起来很棒 - 但我还不完全了解它的用法。

我既没有找到方法也没有找到例子,所以也许这是不可能的,也许它甚至不应该是 - 所以,一个明确的“不,不可能,因为......”当然也是一个有效的答案。

【问题讨论】:

  • 请看here
  • 抱歉,我不明白这与我的问题有什么关系。另请注意,B 的列类别动态取决于 A,因此“y”值的数量可能因情况而异。

标签: r data.table


【解决方案1】:

(归功于 Arun)

A[, setattr(as.list(v), 'names', y), by=x]

【讨论】:

  • [.data.table(A, , setattr(as.list(v), "names", y), by = x) 中的错误:j 不计算为相同数量的列每组
【解决方案2】:

我将选择一个包含不等组的示例,以便更容易说明一般情况:

A <- data.table(x=c(1,1,1,2,2), y=c(1,2,3,1,2), v=(1:5)/5)
> A
   x y   v
1: 1 1 0.2
2: 1 2 0.4
3: 1 3 0.6
4: 2 1 0.8
5: 2 2 1.0

第一步是使每组“x”的元素/条目数相同。这里,对于 x=1,y 有 3 个值,但对于 x=2,只有 2 个。所以,我们必须先用 NA 解决这个问题,因为 x=2, y=3。

setkey(A, x, y)
A[CJ(unique(x), unique(y))]

现在,要将其转换为宽格式,我们应该按“x”分组并在v 上使用as.list,如下所示:

out <- A[CJ(unique(x), unique(y))][, as.list(v), by=x]
   x  V1  V2  V3
1: 1 0.2 0.4 0.6
2: 2 0.8 1.0  NA

现在,您可以使用 setnames 的引用来设置重整列的名称,如下所示:

setnames(out, c("x", as.character(unique(A$y)))

   x   1   2   3
1: 1 0.2 0.4 0.6
2: 2 0.8 1.0  NA

【讨论】:

  • 实际上你的第一个解决方案没有在你的帖子中给出。所以我会出于学术原因保留它!非常感谢您的努力!
  • 第一个解决方案在每个组已经有相等的行时有效。最好在最后设置一次列的名称,而不是为每个组设置它(这是旧解决方案所做的)。在更大的数据上可能会出现性能问题。
  • 好吧,这个解决方案我会在研究手册几周后找到......所以,这可能是非常主观的,但我认为我可以正确地说这个解决方案非常复杂并且详细说明 - 毫无疑问,这可能是我要求的仅使用 data.table 的最简单的解决方案。所以,我想从你那里知道,也许这个重塑数据集的领域并不是 data.table 真正应该解决的问题。关于 data.table 的经济和合理使用,您会在哪里划清界限,以及在哪里求助于其他工具?
  • 计划将meltcast添加到data.table。看FR #2627data.table 仍在发展中。仍有许多功能可能会被发现。所以,我不会把自己局限在它做这个、这个和这个的观点上。如果您认为有一个非常常见的操作或有用的操作并不简单,请添加功能请求。 MatthewDowle 对想法非常开放。另请查看 data.table 邮件列表。
【解决方案3】:

使用dcast()(现在是默认的data.table方法,从版本1.9.5开始;早期版本使用dcast.data.table),如

> dcast(A,x~y)
Using 'v' as value column. Use 'value.var' to override
   x   1   2   3
1: 1 0.2 0.4 0.6
2: 2 0.8 1.0  NA

这很快,无需setnames()

当上面示例中的y 是具有字符级别的因子变量时,它也特别有用——例如'Low', 'Medium', 'High' - 因为CJ() 可能不会按照setnames() 预期的顺序返回带有变量的宽数据,并且最终可能会导致数据被错误标记。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-05
    • 1970-01-01
    • 2019-01-10
    • 2019-02-28
    • 2013-08-24
    • 1970-01-01
    相关资源
    最近更新 更多