首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在R中的数据帧匹配/比较中包含一个误差级别

如何在R中的数据帧匹配/比较中包含一个误差级别
EN

Stack Overflow用户
提问于 2016-08-01 09:45:44
回答 2查看 211关注 0票数 1

我对R是新手,我正在尽我最大的努力(到目前为止,还很好),但是我遇到了一个问题。我有两个数据帧,一个有理论值,另一个有实验值,数据帧不是相同的长度。我想比较这两个数据帧,以找到它们之间的匹配值。由于它是理论值和实验值,我需要在匹配值时包含一个误差级别,比如从理论值中的±0.5。这就是我遇到问题的地方--我不知道如何包含这个错误。

数据帧很安静,很大,但下面是我尝试过的一个例子。

代码语言:javascript
运行
复制
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

合并和匹配都没有错误的空间,比较包似乎也没有帮助。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-01 10:11:39

我们可以使用data.table::foverlaps函数进行重叠合并。首先,我们需要准备数据,为理论值创建范围。

代码语言:javascript
运行
复制
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
票数 0
EN

Stack Overflow用户

发布于 2016-08-03 09:28:20

根据您的评论,您说您只想为每个实验值得到一个单一的理论值,即使多个理论值满足公差。您的意思是,如果有多个候选人满足容忍度,您希望在所有候选人中选择最接近的匹配。但你也说没有必要与每一种价值相匹配。我认为这是一个矛盾。如果需要选择所有理论值中最接近的匹配理论值,则意味着需要将每个实验值与所有理论值进行比较,以确保选择所有理论值中最接近的匹配值。

findInterval()函数适用于这一目的。通过首先对理论向量进行排序,我们可以使用它作为vec参数的findInterval(),这将允许使用二进制搜索,以找到每个实验值的下界。我们可以指定all.inside=T,以确保返回的索引都在排序的理论向量中(而不是指向最后一个元素),然后在相邻元素上执行额外的除法器,以在上层元素实际上更接近实验值时添加1。

最后,我们可以应用公差。从您的问题看来,您可能希望返回NA的实验值,没有匹配的理论值,IOW,其中没有理论值,满足公差。如果上一步中发现的理论值不满足相应的实验值,则可以很容易地在这一点上达到这一要求。

另外,次要的一点:我不知道你为什么把向量定义为字符。我们需要数值来执行这些操作。

因此:

代码语言:javascript
运行
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38695712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档