2013-02-24 28 views
4

我知道使用R強大的矢量處理功能可以使代碼變得更短更高效。我目前還不知道如何...簡化可怕的R代碼來調整行意味着

基本任務是調整每行內的單元格,以使行總數被強制匹配由另一個數據框決定的預定義數字。這樣每個區域的總人口數量被強制爲一定的值(每一行表示一個區域),而從一列移動到下一列的單元格之間的比率保持不變。

做它的醜陋的方式(第一環就是要創建一個示例數據幀;確保能夠做的更好,所有;我只是無法停止使用循環!):

con1 <- array(dim=c(5,3)) 

set.seed(1066) 
for(i in 1:ncol(con1)){ 
con1[,i] <- round(rnorm(n=5,mean=10,sd=3))} 
con1 <- data.frame(con1) 
con2 <- data.frame(array(c(8:13, 9:14, 10:15), dim=c(5,3))) 

apply(con1,1, sum) 
apply(con2,1, sum) # different row totals 

con1.adj <- con1 
for (i in 1:nrow(con1)){ 
    con1.adj[i,1] <- con1[i,1] * (sum(con2[i,])/sum(con1[i,])) 
    con1.adj[i,2] <- con1[i,2] * (sum(con2[i,])/sum(con1[i,])) 
    con1.adj[i,3] <- con1[i,3] * (sum(con2[i,])/sum(con1[i,])) 
} 
con1.adj <- data.frame(con1.adj) 
apply(con1.adj,1, sum) # same row totals 

(背景:從別人的工作中挖出這段代碼並愉快地使用了一段時間,現在看起來很糟糕,因爲我已經在R學習曲線上略微縮減了一點,也希望代碼能夠被其他人重新使用。真的很享受語言,如果我能找到更美麗的方式,我會更加享受它)

+4

'apply(con1,1,sum)'和類似的行在代碼中沒有實際價值。你只需計算總和,不要存儲在任何地方! – iTech 2013-02-24 21:28:12

+1

感謝您的提示,但我已經知道了!它是爲了在家用電腦上執行上述步驟的人的益處。它不包括在我使用的代碼中,這將使它更醜陋(如果這可能:) :) – RobinLovelace 2013-02-24 21:35:03

回答

15

我認爲這一行應該做的工作:

con1.adj <- con1 * rowSums(con2)/rowSums(con1) 
+0

+1非常好... – 2013-02-24 21:56:39

+0

也許添加開始數據'con1 < - data.frame(array(round(rnorm (15,10,3)),dim = c(5,3))); con2 < - data.frame(array(c(8:13,9:14,10:15),dim = c(5,3)))'? :) – 2013-02-24 22:04:16

+4

@AnthonyDamico爲什麼?它是問題中的前7行,所以不需要在答案中重複。 – EDi 2013-02-24 22:07:18

2

這裏是另一個建議,在一個稍微好一點的方式來生成con1

rgen <- function(X,mean=10,sd=3){ 
    round(rnorm(n=length(X),mean=mean,sd=sd)) 
} 

con1 <- data.frame(apply(con1,2,rgen)) 

請注意,您的隨機向量的大小將滿足您array尺寸,你可以通過不同的meansd動態例如apply(con1,2,rgen,5,2)這將生成rnormmean=5sd=2

+0

非常感謝這個有用的提示iTech:只是意識到這是一個關於生成測試數據的評論,而不是嘗試的答案。井井有條。現在我需要零環路wahey! – RobinLovelace 2013-02-24 23:08:08