4

我有一个 data.table 并想在一行的每个子集上应用一个函数。通常一个人会这样做:DT[, lapply(.SD, function), by = y]

但在我的情况下,该函数不返回原子向量,而只是返回一个向量。有机会做这样的事情吗?

library(data.table)
set.seed(9)
DT <- data.table(x1=letters[sample(x=2L,size=6,replace=TRUE)],
                 x2=letters[sample(x=2L,size=6,replace=TRUE)],
                 y=rep(1:2,3), key="y")
DT
#   x1 x2 y
#1:  a  a 1
#2:  a  b 1
#3:  a  a 1
#4:  a  a 2
#5:  a  b 2
#6:  a  a 2

DT[, lapply(.SD, table), by = y]
# Desired Result, something like this:
# x1_a x2_a x2_b
#    3    2    1
#    3    2    1

在此先感谢,另外:我不介意函数的结果是否必须具有固定长度。

4

1 回答 1

5

您只需要取消列出该表,然后强制返回一个列表:

> DTCounts <- DT[, as.list(unlist(lapply(.SD, table))), by=y]
> DTCounts

   y x1.a x2.a x2.b
1: 1    3    2    1
2: 2    3    2    1

.


如果你不喜欢名字中的点,你可以sub把它们去掉:

> setnames(DTCounts, sub("\\.", "_", names(DTCounts)))
> DTCounts

   y x1_a x2_a x2_b
1: 1    3    2    1
2: 2    3    2    1

请注意,如果不是每个组都存在列中的所有值
(即,如果x2=c("a", "b")何时y=1,但x2=c("b", "b")何时y=2
,则上述中断。

解决方案是在计数之前使列因素。

DT[, lapply(.SD, is.factor)]

## OR
columnsToConvert <- c("x1", "x2")  # or .. <- setdiff(names(DT), "y") 
DT <- cbind(DT[, lapply(.SD, factor), .SDcols=columnsToConvert], y=DT[, y])
于 2013-04-07T18:13:02.930 回答