我有一个R
data.table
对象DT
,如下所示:
library(ggplot2)
library(data.table)
DT <- movies[movies$mpaa %in% c("NC-17", "PG", "PG-13", "R"), c("rating", "title", "mpaa")]
setDT(DT)
setnames(DT, colnames(DT), c("Gp", "ID", "FACTOR"))
DT[, FACTOR := droplevels(FACTOR)]
DT[, Gp := as.numeric(as.factor(Gp))]
setkey(DT, ID)
DT <- unique(DT)
DT
Gp ID FACTOR
1: 43 $windle R
2: 61 'A' gai waak PG-13
3: 62 'A' gai waak juk jaap PG-13
4: 39 'R Xmas R
5: 38 'Til There Was You PG-13
---
4899: 57 Zuotian R
4900: 27 Zyosyuu syukeininn Maria R
4901: 57 eXistenZ R
4902: 45 xXx PG-13
4903: 29 xXx: State of the Union PG-13
我正在尝试根据列FACTOR
中的元素汇总Gp
列中的数据。我已经能够实现如下。
k <- vector("list", max(DT$Gp))
for (i in 1:max(DT$Gp)) {
names(k)[i] <- i
k[[i]] <- DT[Gp == i, as.vector(table(FACTOR))]
}
k <- lapply(k, function(x) as.data.frame(t(x)))
k <- rbindlist(k)
setnames(k, old = colnames(k), new = c("NC-17", "PG", "PG-13", "R"))
k$Gp <- row.names(k)
setcolorder(k, c("Gp","NC-17", "PG", "PG-13", "R"))
head(k)
Gp NC-17 PG PG-13 R
1: 1 0 0 0 2
2: 2 0 0 0 1
3: 3 0 0 0 2
4: 4 0 0 0 1
5: 5 0 0 0 2
6: 6 0 0 0 3
对于Gp
的每个级别,我想获得每个FACTOR
级别的记录数。如何仅使用k
更优雅地获得所需的结果data.table
?
答案 0 :(得分:4)
我建议您使用dcast
:
require(data.table) # v1.9.4
dcast.data.table(DT, Gp ~ FACTOR, fun.aggregate = length)
或者从current devel, v1.9.5(及以后的版本),我们可以直接使用dcast()
:
require(data.table) # v1.9.5+
dcast(DT, Gp ~ FACTOR, fun.aggregate = length)
as.list()
是一个S3泛型,并且随着更多组而变得非常慢(由于为每个组分派正确的方法所花费的时间)。 table()
是另一个缓慢的功能。
dcast()
也会自动按Gp
列对结果进行排序。
这是一个足够大的基准来强调差异:
set.seed(1L)
bmark = data.table(Gp = sample(1e5, 1e7, TRUE),
FACTOR = sample(levels(DT$FACTOR), 1e7, TRUE))
print(object.size(bmark), units="Mb")
# 114.4 Mb
system.time(ans1 <- dcast(bmark, Gp ~ FACTOR, fun.aggregate = length))
# user system elapsed
# 0.998 0.026 1.030
system.time(ans2 <- bmark[, as.list(table(FACTOR)), by=Gp])
# user system elapsed
# 14.666 0.141 15.078
identical(ans1, setkey(ans2, Gp))
# [1] TRUE
数据大小约为114MB,这并不是很大,速度可达~15倍。
答案 1 :(得分:2)
您可以在每个as.list(table(FACTOR))
组中使用Gp
:
DT[, as.list(table(FACTOR)), by = Gp]
这给出了结果:
Gp NC-17 PG PG-13 R
1: 43 1 8 26 79
2: 61 2 9 22 77
3: 62 0 7 18 63
4: 39 0 17 24 52
5: 38 1 14 13 77
6: 57 1 11 23 72
7: 48 0 16 29 78
...
(要按照示例输出中Gp
的顺序排序,您可以将其更改为DT[order(Gp), as.list(table(FACTOR)), by = Gp]
)。