簡體   English   中英

我如何在沒有循環的情況下通過數據幀中該級別中另一個因子的子集來操作因子級別內的數據

[英]How can i manipulate data within a factor level by a subset of another factor in that level in a dataframe without loops

我有一個由多次樣品運行(樣品 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's

DF <- na.omit(DF)

使用循環時,上述方法顯然很笨拙。 對於大型數據集,有沒有更好的方法來完成這項任務? 也許dplyr?

試試dplyr

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

我相信這會做到。

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排序,然后將問題屬性設置為NULL all.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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM