我的数据框由多次样品运行的吸收光谱组成(样品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?
答案 0 :(得分:2)
尝试dplyr
:
DF %>%
group_by(group) %>%
mutate(abscorr = Xdata - mean(Xdata[Ydata < 8 & Ydata > 4]))
答案 1 :(得分: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
进行排序,然后将问题属性设置为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