在r中的组条件下从另一个数据帧中找到最接近的对值

时间:2019-05-02 17:31:46

标签: r

我有两个数据帧,df1df2

df1 = read.table(text="group    value
    A   24163
    A   80991
    A   81014
    A   81352
    A   81353
    A   81367
    A   81368
    B   71721
    B   76038
    B   113186
    B   126732
    B   126748
    B   155556", header=T, stringsAsFactors=F)

    df2 = read.table(text="group    value
    A   30000
    A   40000
    A   81360
    B   75000
    B   90000
    B   130000", header=T, stringsAsFactors=F)

我想在同一组下为df2$value中的每个df1$value找到最接近的一对值。一个是df1$value中最接近的值小于df2$value中的值,另一个是同一组下df1 $ value中最接近的值大于df2$value中的值。所以预期的结果:

    df = read.table(text="group value   low high
    A   30000   24163   80991
    A   40000   24163   80991
    A   81360   81353   81367
    B   75000   71721   76038
    B   90000   76038   113186
    B   130000  126748  155556", header=T, stringsAsFactors=F)

我想找到一个不循环的解决方案。

1 个答案:

答案 0 :(得分:0)

通过df2df1group合并会给出所有可能的组合-

x = merge(df2, df1, all.x = TRUE, by = "group")

然后,可以用差异和方向(较高或较低)来表示匹配-

x$diff = x$value.x - x$value.y
x$type = ifelse(x$diff < 0, "high", "low")

绝对差异排序,并按照“方向”删除重复项,仅保留最接近的“高”和“低”-

x = x[order(x$group, abs(x$diff)), ]
x = x[!duplicated(x[, c("group", "value.x", "type")]), ]

带有结果的表如下所示-

##     group value.x value.y   diff type
##  19     A   81360   81353      7  low
##  20     A   81360   81367     -7 high
##  1      A   30000   24163   5837  low
##  8      A   40000   24163  15837  low
##  9      A   40000   80991 -40991 high
##  2      A   30000   80991 -50991 high
##  23     B   75000   76038  -1038 high
##  38     B  130000  126748   3252  low
##  22     B   75000   71721   3279  low
##  29     B   90000   76038  13962  low
##  30     B   90000  113186 -23186 high
##  39     B  130000  155556 -25556 high

需要进行一些重塑和重命名操作,以匹配预期结果df-

中的格式
library(reshape2)
x = dcast(x, group + value.x ~ type, value.var = "value.y")
names(x) = gsub(".x", "", names(x))
x = x[, c("group", "value", "low", "high")]
all.equal(x, df)
## [1] TRUE