2015-02-05 70 views
0

我使用下面的代碼將數據集拆分爲兩部分,並在每部分中執行類似的操作。這兩個結果然後合併在一起。我知道我可能會描述拆分應用組合框架,但我無法想象如何簡化下面的代碼。拆分數據集,對每個組應用不同的操作,然後組合

數據集有4個要更新的變量。 4個變量中的每一個都有一個計算新值的公式,每個公式都有一個不同的公式,總共8個公式。

下面的代碼可能會通過某種程度的矢量化得到改善嗎?它似乎比必要的更冗長。我不確定如何爲每個分割半部執行不同的操作(即使用不同的公式),除了下面的方法。

data <- structure(list(site = c(1L, 1L, 1L, 1L, 1L, 1L), plot = 1:6, 
    C = c(40L, 30L, 10L, 5L, 0L, 0L), E = c(0L, 0L, 0L, 10L, 
    20L, 45L), M = c(0L, 0L, 0L, 0L, 0L, 10L), P = c(1000L, 900L, 
    800L, 500L, 200L, 50L), FF = c(1L, 1L, 1L, 0L, 0L, 0L)), .Names = c("site", 
"plot", "C", "E", "M", "P", "FF"), class = "data.frame", row.names = c(NA, 
-6L)) 

df1 <- data[data$FF == 1,] 
df0 <- data[data$FF == 0,] 

df1$C <- df1$C * 1.1 
df1$E <- df1$E * 0.9 
df1$M <- df1$M * 0.1 
df1$P <- df1$P * 1.01 

df0$C <- df0$C * 0.8 
df0$E <- df0$E * 1.05 
df0$M <- df0$M * 1.01 
df0$P <- df0$P * 1.01 

df.new <- rbind(df1, df0) 
+3

等一下,你用plyr和data.table標記了這個,但還沒有探討如何使用它們呢? – Frank 2015-02-05 20:23:26

+0

我確實通過其他SO問題和答案探索plyr和data.table,以及一些我在這裏沒有重現的微弱嘗試。但是,我認爲如果我有足夠的資金與他們一起編寫代碼,這兩種方法似乎都是合適的。我可以發佈非功能性代碼片段。謝謝。 – nofunsally 2015-02-05 21:21:34

回答

5

有許多工具在R.拆分申請,結合我會傾向於使用data.table包:

require(data.table) 
mydt <- data.table(data) 
mycols <- c('C','E','M','P') 
newcols <- paste0(mycols,'new') 
my1vec <- c(1.1,.9,1,1.01) 
my0vec <- c(.8,1.05,1.01,1.01) 

mydt[FF==1,(newcols):=mapply(`*`,my1vec,.SD,SIMPLIFY=FALSE),.SDcols=mycols] 
mydt[FF==0,(newcols):=mapply(`*`,my0vec,.SD,SIMPLIFY=FALSE),.SDcols=mycols] 

我把新值在新列。如果您想覆蓋舊值(如原始代碼所做的那樣),請使用(mycols)代替(newcols)

0

有可能是一個更簡單的方法來做到這一點,但我覺得這4條線路做你想要什麼:

df.new = data 
df.new$C = ifelse(data$FF==1,data$C*1.1,data$C*0.8) 
df.new$E = ifelse(data$FF==1,data$E*0.9,data$E*1.05) 
df.new$M = ifelse(data$FF==1,data$M*0.1,data$M*1.01) 
df.new$P = ifelse(data$FF==1,data$P*1.01,data$P*1.01) 
0

試試這個:

#define the coefficients in the FF==1 case 
FF1coeffs<-c(1.1,0.9,0.1,1.01) 
#define the coefficients in the FF==0 case 
FF0coeffs<-c(0.8,1.05,1.01,1.01) 
#multiply 
data[,3:6]*(rep(FF1coeffs,each=nrow(data))*data$FF+(1-data$FF)*rep(FF0coeffs,each=nrow(data))) 
1

結合bydo.call這樣:

do.call(rbind, 
    by(data,data$FF, 
    function(data)data*matrix(c(1,1,.8,1.05,1.01,1.01,1), 
     ncol=ncol(data),nrow=nrow(data),byrow=TRUE))) 

也就是說,使用by沿着data$FF分割您的data。將每個塊按照適當的矩陣進行相乘(這是匿名的function)。最後,do.callrbind函數將結果一起綁定到一起。

如果需要,按FF列對結果進行排序。

1

您也可以使用within並使用FF作爲數字變量。它不像一些答案那麼簡短,但它有點冗長。

df.new <- within(data, { 
    C = C * (0.8 + 0.3 * FF) 
    E = E * (1.05 - 0.15 * FF) 
    M = M * (1.01 - 0.91 * FF) 
    P = P * 1.01 }) 
相關問題