合并3个值(指定两个,一个范围内)

时间:2018-11-02 18:29:22

标签: r merge

对不起,标题不完整。希望我能证明我在这里的意思。我有以下数据框(从我的真实数据中简化了):

DF1 
ID  Year    Grade   Season  Score
A   2016      6     Fall     259
B   2017      7     Fall     264
C   2016      6     Fall     263
D   2018      6     Winter   269
E   2016      8     Spring   277

DF2
Grade   Season  Score   Pctl
 6       Fall    261    1
 6       Fall    264    2
 7       Fall    264    9
 8      Spring   267    5
 6      Winter   269    6.5
 8      Spring   277    3

我想得到:

DF3
ID  Year    Grade   Season  Score   Pctl
A   2016    6        Fall    259     1
B   2017    7        Fall    264     9
C   2016    6        Fall    263     1
D   2018    6        Winter  269     6.5
E   2016    8        Spring  277     3

简单地说,鉴于DF1中的季节,成绩和分数,我想附加DF2中的相应Pctl。我了解在大多数情况下,这就像使用merge()并提供指定的“ by”参数一样简单。

但是,虽然“季节”和“成绩”无缝地合并,因为它们具有对应的确切值,但“得分”并不总是这样。

首先,以ID为“ A”为例。他们的分数是259,低于Grade:6Season:FallScore:261。在这种情况下,我希望将pctl分配为1。类似,当分数高于99 pctl分数(此处未显示)时,应将其分配为99。

第二个复杂性由ID“ C”表示,其Score:263介于Pctl 1和2之间。也就是说,它不是1:1映射。发生这种情况时,我只想四舍五入(只要一致就向上或向下)到最接近的分数并提供该Pctl。为了演示的目的,我四舍五入并附加了Pctl 1。

根据我的研究,似乎可以通过条件连接或使用 GenomicRanges 包来完成此操作,但解决方案尚不清楚我。

1 个答案:

答案 0 :(得分:2)

一种data.table方法:

library(data.table)

setkey(setDT(DF1), Grade, Season, Score)
setkey(setDT(DF2), Grade, Season, Score)

DF3 <- DF2[DF1, roll = "nearest"]

在这种情况下,263的Score实际上会得到2,因为它比261更接近264。在您应用的不同情况下,这是一致的。

输出:

   Grade Season Score Pctl ID Year
1:     6   Fall   259  1.0  A 2016
2:     6   Fall   263  2.0  C 2016
3:     6 Winter   269  6.5  D 2018
4:     7   Fall   264  9.0  B 2017
5:     8 Spring   277  3.0  E 2016

但是,您还提到了第99个百分位。

另一件事是,确实确实存在得分恰好介于两个值之间的分数,例如下面的428中的Score,而另一个表仅包含427和429。在这种情况下,百分位数将始终与较低的百分数匹配。

数据:

DF1

   ID Year Grade Season Score
1:  A 2016     6   Fall   259
2:  B 2017     7   Fall   264
3:  C 2016     6   Fall   263
4:  D 2018     6 Winter   269
5:  E 2016     8 Spring   277
6:  F 2017     7 Spring   550
7:  G 2015     6   Fall   428

DF2

   Grade Season Score Pctl
1:     6   Fall   261  1.0
2:     6   Fall   264  2.0
3:     7   Fall   264  9.0
4:     8 Spring   267  5.0
5:     6 Winter   269  6.5
6:     8 Spring   277  3.0
7:     7 Spring   550 99.6
8:     6   Fall   427 84.0
9:     6   Fall   429 88.0

添加第99个百分点的行:

library(data.table)

setkey(setDT(DF1), Grade, Season, Score)
setkey(setDT(DF2), Grade, Season, Score)

DF3 <- DF2[DF1, roll = "nearest"][Pctl > 99, Pctl := 99]

如您所见,在联接表中428的Score与427的Score匹配,并且99.6被替换为99:

DF3

   Grade Season Score Pctl ID Year
1:     6   Fall   259  1.0  A 2016
2:     6   Fall   263  2.0  C 2016
3:     6   Fall   428 84.0  G 2015
4:     6 Winter   269  6.5  D 2018
5:     7   Fall   264  9.0  B 2017
6:     7 Spring   550 99.0  F 2017
7:     8 Spring   277  3.0  E 2016