2014-11-03 27 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