我有一个数据框,它由代表问题的 4 列组成,每列代表响应的 4 个级别。
Q1 Q2
1 A A
2 A B
3 B B
4 C C
5 D D
我想得出一个data.frame
这样的:
question response percent
1 Q2 A 0.2
2 Q2 B 0.4
3 Q2 C 0.2
4 Q2 D 0.2
5 Q1 A 0.4
6 Q1 B 0.2
7 Q1 C 0.2
8 Q1 D 0.2
到目前为止,我一直在使用循环来实现这一点for
,但是我的脚本充满了for
循环,所以我想使用 inreshape2
或 with中的函数来实现这一点lapply
。例如,这段代码比for
循环干净得多,但仍然不是我想要的。任何帮助将不胜感激!
这是我到目前为止所得到的:
lapply(lapply(df, summary), function(x) x/sum(x))
编辑:包括每个请求的数据框示例。本来担心关卡标签太长会占用太多空间,所以我把它们缩短了。
dput(df[1:4,])
structure(list(Q1 = structure(c(4L, 4L, 1L, 4L), .Label = c("1.A",
"1.B", "1.C", "1.D"), class = "factor"),
Q2 = structure(c(4L, 4L, 4L, 1L), .Label = c("2.A","2.B",
"2.C", "2.D"), class = "factor"),
Q3 = structure(c(4L, 3L, 4L, 4L), .Label = c("3.A","3.B",
"3.C","3.D"), class = "factor"),
Q4 = structure(c(3L, 1L, 3L, 3L), .Label = c("4.A","4.B",
"4.C","4.D")),
.Names = c("Q1.pre", "Q2.pre", "Q3.pre", "Q4.pre"), row.names = c(NA, 4L),
class = "data.frame")
我发现 Lafortune 和 user20650 的回答结合起来给了我几乎正是我一直在寻找的东西:
melt(sapply(df, function(x) prop.table(table(x))))
然而有一个问题。在sapply
级别上, 与dimnames
Q1 级别的标签名称相同,因此在执行melt
的输出后sapply
,Var1 列只是 Q1s 级别的重复,而我希望 Var1 在 Q1 中具有 Q1 的级别行,Q2 行中的 Q2 级别等。我找到了一种解决方法,方法是将levels
所有列拉到一个单独的变量qnames
中,然后再执行任何操作,df
如下所示:
qnames = melt(sapply(df, levels))
qnames = qnames[ ,3]
melt(sapply(df, function(x) prop.table(table(x))))
df = cbind(qnames, df)
这正是我需要的结果。我有兴趣看看是否有办法在没有额外的情况下实现这一点sapply
and cbind
,所以我将把这个问题留得更久一点。谢谢你的帮助!