我们有DF
df <- data.frame(group=as.factor(rep(c("UP","DOWN"),6)),variables=(rep(c("sex","smoke","sport"),each=4))
,values=as.factor(c(1,1,1,0 ,1,1,0,0, 1,1,1,1)))
group variables values
1 UP sex 1
2 DOWN sex 1
3 UP sex 1
4 DOWN sex 0
5 UP smoke 1
6 DOWN smoke 1
7 UP smoke 0
8 DOWN smoke 0
9 UP sport 1
10 DOWN sport 1
11 UP sport 1
12 DOWN sport 1
>
现在我想知道所有级别的所有计数
library(plyr)
这个命令几乎完全符合我的要求
count(df, c("variables", "group", "values"))
variables group values freq
1 sex DOWN 0 1
2 sex DOWN 1 1
3 sex UP 1 2
4 smoke DOWN 0 1
5 smoke DOWN 1 1
6 smoke UP 0 1
7 smoke UP 1 1
8 sport DOWN 1 2
9 sport UP 1 2
我还想计算未观察到的因子水平。就像我在下面的输出中一样。
variables group values freq
1 sex DOWN 0 1
2 sex DOWN 1 1
3 sex UP 0 0 <--
4 sex UP 1 2
5 smoke DOWN 0 1
6 smoke DOWN 1 1
7 smoke UP 0 1
8 smoke UP 1 1
9 sport DOWN 0 0 <--
10 sport DOWN 1 2
11 sport UP 0 0 <--
12 sport UP 1 2
如何实现上述输出?
答案 0 :(得分:2)
您也可以使用data.table
执行此操作,代码行数较少:
library(data.table)
dt <- setDT(df)
cj <- CJ(dt$variables, dt$group, dt$values, unique = TRUE)
dt[, .N, keyby = c("variables", "group", "values")][cj][is.na(N), N := 0]
print(dt)
variables group values N
1: sex DOWN 0 1
2: sex DOWN 1 1
3: sex UP 0 0
4: sex UP 1 2
5: smoke DOWN 0 1
6: smoke DOWN 1 1
7: smoke UP 0 1
8: smoke UP 1 1
9: sport DOWN 0 0
10: sport DOWN 1 2
11: sport UP 0 0
12: sport UP 1 2
setDT()
通过引用将data.frame
转换为data.table
,即无需复制。
CJ()
是一个交叉联接。它从向量的叉积形成data.table
。因此,它是data.table
的{{1}}版本。
参数expand.grid
是在unique = TRUE
或level()
中包装每个参数的便捷替代方法。
按小组计算是使用unique()
:
dt[, .N, keyby = c("variables", "group", "values")]
现在, variables group values N
1: sex DOWN 0 1
2: sex DOWN 1 1
3: sex UP 1 2
4: smoke DOWN 0 1
5: smoke DOWN 1 1
6: smoke UP 0 1
7: smoke UP 1 1
8: sport DOWN 1 2
9: sport UP 1 2
(右)将dt[, .N, keyby = c("variables", "group", "values")][cj]
结果加入所有可能的组合。
最后,CJ()
将[is.na(N), N := 0]
列中的所有NA
替换为N
。
答案 1 :(得分:1)
你也可以这样做:
library(plyr)
d1 <- count(df, c("variables", "group", "values"))
d2 <- expand.grid(list(levels(df$variables), levels(df$group), levels(df$values)))
d2$freq <- 0
colnames(d2) <- colnames(d1)
m <- merge(d1, d2, by = c("variables", "group", "values"), all.y = T)[,-5]
m[is.na(m)] <- 0
# variables group values freq.x
# 1 sex DOWN 0 1
# 2 sex DOWN 1 1
# 3 sex UP 0 0
# 4 sex UP 1 2
# 5 smoke DOWN 0 1
# 6 smoke DOWN 1 1
# 7 smoke UP 0 1
# 8 smoke UP 1 1
# 9 sport DOWN 0 0
# 10 sport DOWN 1 2
# 11 sport UP 0 0
# 12 sport UP 1 2
我们的想法是创建一个数据框(名为d2
),其中生成variables
和group
和values
的所有可能组合,然后将其与d1
合并{1}}。
答案 2 :(得分:0)
这是一个想法。您可以根据freq
变量复制行。如果freq为2,则复制的行将具有唯一的rowname,我们可以将其定位并将其freq
和values
更改为0.
df1 <- plyr::count(df, c("variables", "group", "values"))
df2 <- df1[rep(row.names(df1), df1$freq),]
df2$freq[grep('.', row.names(df2), fixed = TRUE)] <- 0
df2$values[df2$freq == 0] <- 0
df2
# variables group values freq
#1 sex DOWN 0 1
#2 sex DOWN 1 1
#3 sex UP 1 2
#3.1 sex UP 0 0
#4 smoke DOWN 0 1
#5 smoke DOWN 1 1
#6 smoke UP 0 1
#7 smoke UP 1 1
#8 sport DOWN 1 2
#8.1 sport DOWN 0 0
#9 sport UP 1 2
#9.1 sport UP 0 0
如果你想重置你的rownames那么,
row.names(df2) <- NULL