我有两个数据帧,df1
和df2
:
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)
我想找到一个不循环的解决方案。
答案 0 :(得分:0)
通过df2
将df1
与group
合并会给出所有可能的组合-
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