在整个DF上运行prop.table

时间:2014-11-03 01:30:53

标签: r

所以我试图在客户调查中运行频率。该调查有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:我已经为此工作了四天,无法在线找到解决方案。对不起,这太基础了。我对此非常陌生。

2 个答案:

答案 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