2017-09-28 106 views
2

我有一個數據框組成的吸收光譜從多個樣本運行(樣本a,b,c,d) ,其中Ydata是波長,Xdata是吸收。我正在計算基線校正吸收,方法是從感興趣的峯值中減去安靜波長範圍內的平均吸收值。我怎樣才能操縱一個因素水平的數據框中的一個子集的另一個因素在一個數據框沒有循環

簡化數據幀:

DF <- data.frame(
    group = rep(c("a", "b", "c", "d"),each=10), 
    Ydata = rep(1:10, times = 4), 
    Xdata = c(seq(1,10,1),seq(5,50,5),seq(20,11,-1),seq(0.3,3,0.3)), 
    abscorr = NA 
) 

我需要更正減去運行中的子集化的波長範圍的平均運行每個樣品。我一直在做這樣說:

for (i in 1:length(levels(DF$group))){ 
    sub1 <- subset(DF, group == levels(DF$group)[i], select = c(group, Ydata, 
    Xdata)); 
    sub2 <- subset(sub1, Ydata > 4 & Ydata < 8, select = c(group, Ydata, 
    Xdata)); 
    sub1$abscorr <- sub1$Xdata - mean(sub2$Xdata); 
    DF <- rbind(sub1, DF); 
} 

,然後收拾所有的「NA的

DF <- na.omit(DF) 

上面做的方式是使用循環明顯笨重。是否有更好的方法去處理大數據集的這個任務?也許dplyr?

回答

2

嘗試dplyr

DF %>% 
    group_by(group) %>% 
    mutate(abscorr = Xdata - mean(Xdata[Ydata < 8 & Ydata > 4])) 
+0

謝謝MT!工作一種享受。我無法理解dplyr軟件包的工作方式。 – Jordan

0

我相信這樣做。

fun <- function(x){ 
    x$Xdata - mean(x[which(x$Ydata > 4 & x$Ydata < 8), "Xdata"]) 
} 
DF$abscorr <- do.call(c, lapply(split(DF, DF$group), fun)) 

需要注意的是,當我測試,all.equal給了我一個系列的差異,即兩個結果的屬性是不同的。所以我跑了以下。

fun <- function(x){ 
    x$Xdata - mean(x[which(x$Ydata > 4 & x$Ydata < 8), "Xdata"]) 
} 
DF2 <- DF 
DF2$abscorr <- do.call(c, lapply(split(DF2, DF2$group), fun)) 

all.equal(DF[order(DF$group, DF$Ydata), ], DF2) 
# [1] "Attributes: < Names: 1 string mismatch >"           
# [2] "Attributes: < Length mismatch: comparison on first 2 components >"     
# [3] "Attributes: < Component 2: names for target but not for current >"     
# [4] "Attributes: < Component 2: Attributes: < Modes: list, NULL > >"     
# [5] "Attributes: < Component 2: Attributes: < Lengths: 1, 0 > >"      
# [6] "Attributes: < Component 2: Attributes: < names for target but not for current > >" 
# [7] "Attributes: < Component 2: Attributes: < current is not list-like > >"    
# [8] "Attributes: < Component 2: target is omit, current is numeric >"     
# [9] "Component 「abscorr」: Modes: numeric, logical"          
#[10] "Component 「abscorr」: target is numeric, current is logical" 

正如你所看到的沒有什麼區別在abscorr的計算值,只能在屬性。其中,na.omit屬性或rownames存在差異。如果我是你,我不會擔心,因爲abscorr的值是相等的。

編輯。
請注意,如果我排序DF,然後將問題屬性設置爲NULLall.equal和更嚴格identical返回TRUE

DF1 <- DF[order(DF$group, DF$Ydata), ] # Modify a copy, keep the original 
row.names(DF1) <- NULL 
attr(DF1, "na.action") <- NULL 

all.equal(DF1, DF2) 
#[1] TRUE 
identical(DF1, DF2) 
#[1] TRUE 
+0

感謝魯伊 - 一個很好的基礎-R解決方案! – Jordan

相關問題