13
> 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

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

手册中的一个随机示例:

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

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

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

4

3 回答 3

16

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

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”分组并使用as.liston v,如下所示:

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
于 2013-08-04T21:50:27.067 回答
13

使用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当在上面的示例中是具有字符级别的因子变量时,它也特别有用——例如“低”、“中”、“高”——因为CJ()可能不会以setnames()预期的顺序返回具有变量的宽数据,并且您最终可能会导致您的数据被错误标记。

于 2014-04-25T22:28:24.087 回答
2

(归功于 Arun)

A[, setattr(as.list(v), 'names', y), by=x]
于 2013-08-04T21:46:09.927 回答