我对R是新手,我正在尽我最大的努力(到目前为止,还很好),但是我遇到了一个问题。我有两个数据帧,一个有理论值,另一个有实验值,数据帧不是相同的长度。我想比较这两个数据帧,以找到它们之间的匹配值。由于它是理论值和实验值,我需要在匹配值时包含一个误差级别,比如从理论值中的±0.5。这就是我遇到问题的地方--我不知道如何包含这个错误。
数据帧很安静,很大,但下面是我尝试过的一个例子。
Theory <- c("195.0882",
"196.0852",
"196.0916",
"300.1600",
"288.1752",
"289.1786",
"290.1819",
"393.2077",
"394.2111")
Experi <- c("195.0312",
"196.0340",
"196.1251",
"288.1856",
"289.1786",
"290.1819")
T <- data.frame(Theory)
E <- data.frame(Experi)
M1 <- merge.default(T, E)
M2 <- match(Theory, Experi)
M2
# [1] NA NA NA NA NA 5 6 NA NA
合并和匹配都没有错误的空间,比较包似乎也没有帮助。
发布于 2016-08-01 02:11:39
我们可以使用data.table::foverlaps
函数进行重叠合并。首先,我们需要准备数据,为理论值创建范围。
library(data.table)
# set tolerance for merge
tolerance <- 0.5
# Theory data, prepare data with tolerance for Start/End
dt_T <- data.table(
Theory = as.numeric(Theory),
Start = as.numeric(Theory) - tolerance,
End = as.numeric(Theory) + tolerance,
key= c("Start", "End"))
# Experi data, Start/End are the same
dt_E <- data.table(
Experi = as.numeric(Experi),
Start = as.numeric(Experi),
End = as.numeric(Experi),
key= c("Start", "End"))
# merge with overlap
foverlaps(dt_E, dt_T)
# Theory Start End Experi i.Start i.End
# 1: 195.0882 194.5882 195.5882 195.0312 195.0312 195.0312
# 2: 196.0852 195.5852 196.5852 196.0340 196.0340 196.0340
# 3: 196.0916 195.5916 196.5916 196.0340 196.0340 196.0340
# 4: 196.0852 195.5852 196.5852 196.1251 196.1251 196.1251
# 5: 196.0916 195.5916 196.5916 196.1251 196.1251 196.1251
# 6: 288.1752 287.6752 288.6752 288.1856 288.1856 288.1856
# 7: 289.1786 288.6786 289.6786 289.1786 289.1786 289.1786
# 8: 290.1819 289.6819 290.6819 290.1819 290.1819 290.1819
发布于 2016-08-03 01:28:20
根据您的评论,您说您只想为每个实验值得到一个单一的理论值,即使多个理论值满足公差。您的意思是,如果有多个候选人满足容忍度,您希望在所有候选人中选择最接近的匹配。但你也说没有必要与每一种价值相匹配。我认为这是一个矛盾。如果需要选择所有理论值中最接近的匹配理论值,则意味着需要将每个实验值与所有理论值进行比较,以确保选择所有理论值中最接近的匹配值。
findInterval()
函数适用于这一目的。通过首先对理论向量进行排序,我们可以使用它作为vec
参数的findInterval()
,这将允许使用二进制搜索,以找到每个实验值的下界。我们可以指定all.inside=T
,以确保返回的索引都在排序的理论向量中(而不是指向最后一个元素),然后在相邻元素上执行额外的除法器,以在上层元素实际上更接近实验值时添加1。
最后,我们可以应用公差。从您的问题看来,您可能希望返回NA的实验值,没有匹配的理论值,IOW,其中没有理论值,满足公差。如果上一步中发现的理论值不满足相应的实验值,则可以很容易地在这一点上达到这一要求。
另外,次要的一点:我不知道你为什么把向量定义为字符。我们需要数值来执行这些操作。
因此:
theory <- c(195.0882,196.0852,196.0916,300.16,288.1752,289.1786,290.1819,393.2077,394.2111);
experi <- c(195.0312,196.034,196.1251,288.1856,289.1786,290.1819);
## sort theory for findInterval() binary search
theory <- sort(theory);
## get closest match for each experi element
i <- findInterval(experi,theory,all.inside=T);
inc <- which(abs(theory[i+1L]-experi)<abs(theory[i]-experi));
i[inc] <- i[inc]+1L;
## init result vector
res <- theory[i];
## replace with NA any result elements whose deviations exceed the tolerance
res[abs(res-experi)>0.5] <- NA_real_;
## show result in a nice format
data.frame(experi,res,error=experi-res);
## experi res error
## 1 195.0312 195.0882 -0.0570
## 2 196.0340 196.0852 -0.0512
## 3 196.1251 196.0916 0.0335
## 4 288.1856 288.1752 0.0104
## 5 289.1786 289.1786 0.0000
## 6 290.1819 290.1819 0.0000
https://stackoverflow.com/questions/38695712
复制相似问题