所以我试图在客户调查中运行频率。该调查有108个变量,响应编号为1-5,其中9个是我们的NA。一些变量是基于文本的。原始数据如下所示:
Q1 Q2 Q3 Q4
1 3 2 Mazda
2 3 4 Ford
3 5 2 Toyota
9 3 2 Hyundai
理想情况下,我想知道对于108个变量中的每一个,有多少人以这种格式回答每个问题。例如,我的新数据框中的第一列是:
Q1
1 25%
2 25%
3 25%
4 0%
5 0%
9 25%
我尝试过使用
Frequencies = apply(df, 2, table)
它将其作为列表吐出。我想然后运行这个列表
prop.table(Frequencies, 2)
获取列百分比。但是,我收到错误“margin.table(x,margin)中的错误:'x'不是数组。”
我已经玩了几天,将频率转换为数据框但没有运气。有什么想法吗?
谢谢!
PS:我已经为此工作了四天,无法在线找到解决方案。对不起,这太基础了。我对此非常陌生。答案 0 :(得分:3)
尝试:
> ddf
Q1 Q2 Q3 Q4
1 1 3 2 Mazda
2 2 3 4 Ford
3 3 5 2 Toyota
4 9 3 2 Hyundai
>
> sapply(apply(ddf, 2, table), function(x) x/sum(x))
$Q1
1 2 3 9
0.25 0.25 0.25 0.25
$Q2
3 5
0.75 0.25
$Q3
2 4
0.75 0.25
$Q4
Ford Hyundai Mazda Toyota
0.25 0.25 0.25 0.25
或者,正如@DavidArenburg在评论中建议的那样:
lapply(ddf, function(x) prop.table(table(x)))
答案 1 :(得分:1)
首先,您需要将列格式化为您关注的级别的因子。然后,您可以使用?lapply将函数应用于列表(数据框是一种列表)。您需要在lapply()
调用中编写自定义函数以执行您想要的操作。 lapply()
的输出是另一个列表,因此您可以将其嵌套在as.data.frame()
中,以便在设置因子级别时将其重新置于数据框中。对于最后一次lapply()
调用,您最好将其保留为列表,否则R将recycle较短的输出使其长度与较长的输出相同。
df <- read.table(text="Q1 Q2 Q3 Q4
1 3 2 Mazda
2 3 4 Ford
3 5 2 Toyota
9 3 2 Hyundai", header=TRUE)
dfQs <- as.data.frame(lapply(df[,1:3], function(x){ factor(x, levels=c(1:5,9)) }) )
dfQs$Q4 <- as.factor(df$Q4)
dfQs
# Q1 Q2 Q3 Q4
# 1 1 3 2 Mazda
# 2 2 3 4 Ford
# 3 3 5 2 Toyota
# 4 9 3 2 Hyundai
proportions <- lapply(dfQs, function(x){ prop.table(table(x)) })
proportions
# $Q1
# 1 2 3 4 5 6 7 8 9
# 0.25 0.25 0.25 0.00 0.00 0.00 0.00 0.00 0.25
# $Q2
# 1 2 3 4 5 6 7 8 9
# 0.00 0.00 0.75 0.00 0.25 0.00 0.00 0.00 0.00
# $Q3
# 1 2 3 4 5 6 7 8 9
# 0.00 0.75 0.00 0.25 0.00 0.00 0.00 0.00 0.00
# $Q4
# Ford Hyundai Mazda Toyota
# 0.25 0.25 0.25 0.25