关于r:以另一个数据帧为条件将值添加到数据帧


Adding values to a data frame conditional on another data frame

这可能是一个非常简单的问题,但是即使浏览了许多类似的帖子,我也很难弄清楚。

我有两个数据框,dvaluessvalues

dvalues

1
2
3
4
5
6
district   districtID   value    state
Badgam     1002          30.2    N/A
Pulwama    1012          10.9    N/A
Kangra     2002          10.2    N/A
Amritsar   3015          29.8    N/A
...

svalues

1
2
3
4
5
state            stateID
Jammu & Kashmir     1000
Himachal Pradesh    2000
Punjab              3000
....

我想在状态栏中为每一行添加一个值,条件是districtID值介于两个stateID值之间。

例如,由于BadgamPulwama(文件1中的前两个值)的districtID值在1000到2000之间,因此状态名称应为"Jammu & Kashmir"。 同样,ID在2000到3000之间的区Kangra应该具有州名"Himachal Pradesh"

我的最终结果应该是什么样的:

1
2
3
4
5
6
district   districtID   value    state
Badgam     1002          30.2    Jammu & Kashmir
Pulwama    1012          10.9    Jammu & Kashmir
Kangra     2002          10.2    Himachal Pradesh
Amritsar   3015          29.8    Punjab
...

在许多尝试中,这是唯一有效的方法:

1
2
3
4
5
6
dvalues$state<-
 ifelse(dvalues$districtID<2000,"Jammu & Kashmir",
  ifelse(dvalues$districtID>2000 & dvalues$districtID<3000,"Himachal Pradesh",
    ifelse(dvalues$districtID>3000 & dvalues$districtID<4000,"Punjab",
      ifelse(dvalues$districtID>4000 & dvalues$districtID<5000,"Chandigarh",
       ...

但是,这很慢且很丑,更不用说有36行了-我想知道是否有更优雅的解决方案。

谢谢,我非常感谢您的回答。


如果您的间隔始终保持为一千,那么一个简单的解决方法是-

1
2
dvalues$stateID <- dvalues$districtID - (dvalues$districtID %% 1000)
dvalues <- merge(dvalues, svalues, by = 'stateID')

但总的来说,对于这种间隔内合并的情况,我使用data.tableroll参数-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
library(data.table)

# converting data.frames to data.tables
svalues <- data.table(svalues)
dvalues <- data.table(dvalues)

# removing state column from dvalues as we will be getting that from svalues
dvalues[,state := NULL]

#setting keys
setkeyv(svalues,'stateID')
setkeyv(dvalues,'districtID')

# merging the data sets based on values in the key columns
# roll = Inf looks for the previous matching value on the key and merges with that
# see help entry for data.table to understand more
svalues[dvalues, roll = +Inf]