我在数据帧上使用reshape2函数dcast。其中一个变量是某些级别未出现在数据框中的因素,但我会在创建的新列中包含所有值。
例如说我运行以下
library(reshape2)
dataDF <- data.frame(
id = 1:6,
id2 = c(1,2,3,1,2,3),
x = c(rep('t1', 3), rep('t2', 3)),
y = factor(c('A', 'B', 'A', 'B', 'B', 'C'), levels = c('A', 'B', 'C', 'D')),
value = rep(1)
)
dcast(dataDF, id + id2 ~ x + y, fill = 0)
我得到以下
id id2 t1_A t1_B t2_B t2_C
1 1 1 1 0 0 0
2 2 2 0 1 0 0
3 3 3 1 0 0 0
4 4 1 0 0 1 0
5 5 2 0 0 1 0
6 6 3 0 0 0 1
但我也希望包括列为t1_C,t1_D,t2_A和t2_D的列为0&#39;
即。我想要以下
id id2 t1_A t1_B t1_C t1_D t2_A t2_B t2_C t2_D
1 1 1 1 0 0 0 0 0 0 0
2 2 2 0 1 0 0 0 0 0 0
3 3 3 1 0 0 0 0 0 0 0
4 4 1 0 0 0 0 0 1 0 0
5 5 2 0 0 0 0 0 1 0 0
6 6 3 0 0 0 0 0 0 1 0
此外,作为aisde,是否可以创建上述内容而无需使用列&#39;值&#39;在初始数据帧中充满了一些。基本上只是想投x&amp; y在他们自己的列中,如果它们存在于该id中,则为1。
提前致谢
编辑: 最初在LHS上有一个变量,Jeremy在下面回答,但实际上LHS上有一个以上的变量,所以编辑的问题反映了这个
答案 0 :(得分:8)
尝试在您的dcast调用中添加drop = FALSE
,以便不会丢弃未使用的因子级别:
dcast(dataDF, id ~ x + y, fill = 0, drop = FALSE)
id t1_A t1_B t1_C t1_D t2_A t2_B t2_C t2_D
1 1 1 0 0 0 0 0 0 0
2 2 0 1 0 0 0 0 0 0
3 3 1 0 0 0 0 0 0 0
4 4 0 0 0 0 0 1 0 0
5 5 0 0 0 0 0 1 0 0
6 6 0 0 0 0 0 0 1 0
除此之外,是的,我们只需要使用[{1}}函数告诉dcast
您想要的内容,在这种情况下您需要aggregate
:
length
对于您的修改,我会使用data2 <- dataDF[,1:3]
dcast(data2, id ~ x + y, fill = 0, drop = FALSE, fun.aggregate = length)
和tidyr
而不是dplyr
:
reshape2
首先,我们使用library(tidyr)
library(dplyr)
dataDF %>% left_join(expand.grid(x = levels(dataDF$x), y = levels(dataDF$y)), .) %>%
unite(z, x, y) %>%
spread(z, value, fill = 0) %>%
na.omit
并合并完成x和y的所有组合,然后我们expand.grid
将它们分成一列z,然后我们unite
将它们删除,然后从中删除NA id列:
spread