2014-09-02 73 views
0

我試圖使用一個自定義函數,它從一個data.frame(raw_DF)獲取一行數據,並使用來自單獨data.frame(calibrant_DF)的校準數據,然後計算Raw12的校準值。我收到此錯誤:如何將多個data.frames作爲R中的輸入應用自定義函數?

Error in cal_DF$Cal_set : $ operator is invalid for atomic vectors Called from: top level

看來,應用功能不喜歡有data.frame傳遞給它的這種方式,所以我已經花了幾年時間試圖弄清楚,如果我可以使用一個不同的應用函數(例如mapply,lapply)或plyr函數來完成我想要做的事情,但沒有任何運氣。建議?

示例代碼(真正的功能和DF的更爲複雜):

raw_DF<-data.frame("Cal_set"=c(1,2,1,2),"Raw12"=c(3.3,3.1,5.1,4.2)) 
calibrant_DF<-data.frame("Cal_set"=c(1,2),"b12"=c(.01,.04),"m12"=c(.95,.99)) 

apply.cals <- function(raw_row,cal_DF){ 
    current_cals<-cal_DF[which(cal_DF$Cal_set==raw_row$Cal_set),] 
    raw12<-raw_row$Raw12 
    cal12<-(raw12-current_cals$b12)/current_cals$m12 

    outdata<-data.frame(raw12,cal12) 
    return(outdata) 
} # End of apply.cals 

calibrated_data<-apply(X=raw_DF,MARGIN=1,FUN=apply.cals,cal_DF="calibrant_DF") 

而我所需的輸出是一個data.frame(或東西我可以放到一個data.frame)這樣的結果:

raw12 cal12 3.3 3.463158 3.1 3.090909 5.1 5.357895 4.2 4.20202

感謝您的任何建議!

編輯 - 解決了,但.... 我會對plyr解決方案感興趣,如果其他人有一個想法 - 這是一個函數,我想更好地理解,我的印象是,這可能是一個問題優雅地處理。

+0

你的功能被寫成如果參數'cal_DF'是' data.frame'(大概;可能是一些其他的二維對象),但是你傳遞給calicy_DF「',它是一個原子字符矢量,而不是'data.frame'。如果您嘗試從全局環境傳遞對象'calibrant_DF',請不要引用其名稱。 – nrussell 2014-09-02 20:19:13

+0

編輯代碼以刪除這些引號後,我收到一個不同的但類似的錯誤:'在raw_row $ Cal_set:$運算符中的錯誤對原子向量無效 調用自:'[.data.frame'(cal_DF,which(cal_DF $ Cal_set == raw_row $ Cal_set), )' – DirtStats 2014-09-02 20:30:40

+0

您能否提供您想要的輸出示例 - 我不能肯定地說,但我懷疑'apply'對於您嘗試完成的任何操作都是錯誤的函數。 – nrussell 2014-09-02 20:38:36

回答

1

apply需要一個矩陣 - 如果它獲得一個數據幀,它會將其轉換爲矩陣。所以你不能依靠$apply

One可以快速將代碼轉換的東西,工作方式是:

sapply(split(raw_DF, rownames(raw_DF)), apply.cals, cal_DF=calibrant_DF) 

split(raw_df, rownames(raw_DF))轉換raw_DF到一個列表,其中每個組件是隻有一個行的數據幀。並且sapply將您的功能應用於每個這樣的數據幀。

我所得到的在這個例子是:

#  1  2  3  4  
# raw12 3.3  3.1  5.1  4.2  
# cal12 3.463158 3.090909 5.357895 4.20202 

(我希望輸出產生任何意義,你...)

+0

Btw ..如果你使用上面的方法,我建議你改變函數bove - 返回一個向量而不是數據框,就像'outdata <-c(raw = raw12,cal = cal12)'。這與'sapply'結合起來更好,它將結果放入矩陣中(數據幀被強制轉換爲矩陣是一種醜陋的數據結構)。或者,你可以使用'lapply'而不是'sapply',然後用'do.call(rbind,....)'加入部分 - 然後你得到一個數據幀作爲輸出。我相信'plyr'也可以做到這一點,也許可以用更短的方式。 – lebatsnok 2014-09-02 20:56:00

+0

謝謝,你的解決方案應該能夠工作 - 我想在列中得到結果,但轉置很容易。我會給它一個鏡頭。 – DirtStats 2014-09-02 21:09:58

+0

解決方案效果很好!我只是在輸出中添加了一個data.frame(t())包裝器,以完全按照我的意願來獲取它。 – DirtStats 2014-09-04 20:43:01

相關問題