我想用dcast更改data.table中的列,但我不希望它是二进制值(0/1)还是不在级别中
例如此data.table:
dt1 <- data.table::data.table("ID" = 1:4,'Col0' = c(1, 0, 1, 0),'Col1' = c('a', 'b', 'c', 'a'),'Col2' = (letters[20:23]),'Col3' = factor(c("a", "b", NA, "a"),levels = c("a", "b", "c")))
我在尝试dcast之前添加了ID,但我们可以移动此值
我尝试过这种方法,但是就像我在对级别和二进制文件有问题之前进行介绍一样。
res = data.table::dcast(data.table::melt(dt1, id.vars='ID'), ID ~ variable + value, fun = length)
我试图得到这个结果。
result <- data.table::data.table('Col0' = c(1, 0, 1, 0),'Col1_a' = c(1, 0, 0, 1),'Col1_b' = c(0, 1, 0, 0),'Col1_c' = c(0, 0, 1, 0),'Col2_t' = c(1, 0, 0, 0),'Col2_u' = c(0, 1, 0, 0),'Col2_v' = c(0, 0, 1, 0),'Col2_w' = c(0, 0, 0, 1), 'Col3_a' = c(1, 0, NA, 1),'Col3_b' = c(0, 1, NA, 0))
答案 0 :(得分:0)
以下是一些替代方案:
1)model.matrix 函数mm
基于列nm
定义模型矩阵,并将NA作为级别。将其应用于除ID
以外的每一列,并删除全为零或名称为NA
的那些列。
mm <- function(nm) model.matrix(~.-1, setNames(list(addNA(dt1[[nm]])), nm))
res <- do.call("cbind", lapply(names(dt1)[-1], mm))
res[, colSums(res) > 0 & !grepl("NA", colnames(res)) ]
给予:
Col00 Col01 Col1a Col1b Col1c Col2t Col2u Col2v Col2w Col3a Col3b
1 0 1 1 0 0 1 0 0 0 1 0
2 1 0 0 1 0 0 1 0 0 0 1
3 0 1 0 0 1 0 0 1 0 0 0
4 1 0 1 0 0 0 0 0 1 1 0
2)熔化/广播使用data.table中的melt
和dcast
将每一列转换为因数,最后删除名称包括NA
的列
m <- melt(replace(dt1, TRUE, lapply(dt1, factor)), id.vars='ID')
res = dcast(m, ID ~ variable + value, fun = length)
subset(res, select = !grepl("NA", colnames(res)) )[, -1]
给予:
Col0_0 Col0_1 Col1_a Col1_b Col1_c Col2_t Col2_u Col2_v Col2_w Col3_a Col3_b
1: 0 1 1 0 0 1 0 0 0 1 0
2: 1 0 0 1 0 0 1 0 0 0 1
3: 0 1 0 0 1 0 0 1 0 0 0
4: 1 0 1 0 0 0 0 0 1 1 0