2014-11-03 26 views
2

所以我试图在客户调查中运行频率。调查有108个变量,回答编码为1-5,其中9个是我们的NA。一些变量是基于文本的。原始数据看起来是这样的:在整个DF上运行prop.table

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:我一直在为此工作四天,无法在线找到解决方案。对不起,这很基本。我对此很新。

+1

请发表一个可重复使用的小例子。 – 2014-11-03 01:54:38

+0

我已经更新了一小段我的数据。那是你要求的吗? @Glen_b – 2014-11-03 02:27:47

+0

每个问题的评分是1:9的等级吗? – gung 2014-11-03 03:17:22

回答

2

尝试:

> 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))) 
+0

为什么要运行双循环?刚才lapply(df,function(x)prop.table(table(x)))''有什么问题? – 2014-11-03 10:24:51

+0

@DavidArenburg你是对的。由于OP已经在使用apply(ddf,2,table),我只是试图完成他的代码。 – rnso 2014-11-03 12:37:44

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 
+0

(+1)这几乎是正确的答案,除了他不需要全部9个等级,只有1:5和9(对于NA)。第二个问题是,这不是一个通用的解决方案,我不认为他会手动运行所有的分类变量。总之,一般的解决方案只是'lapply(df,function(x)if(is.numeric(x))prop.table(table(factor(x,levels = c(1:5,9))))) else prop.table(table(x)))''。在这里你不需要'as.data.frame',因为看起来每列的输出长度总是不一样的,所以把它作为列表 – 2014-11-03 10:34:20

+0

@DavidArenburg,谢谢关于关卡的提示,我错过了。我更喜欢做两个明确的'lapply's,而不是像'lapply'那样嵌套'if'。它确实需要更多的线条,但更容易看到它展开,国际海事组织。 – gung 2014-11-03 14:20:34