给定逻辑条件,在同一列上进行操作

时间:2018-11-13 21:18:49

标签: r

我有这种形式的数据框

distance city obs
9        0    1
5        1    2
7        0    3
6        0    4
5        0    5
10       1    6
11       0    7
15       0    8

我想创建一个新的“差异”列,该列计算每个观测值与其最接近的城市(按列距离中的值)之间的“距离”列中的值之差。

换句话说,我想拥有这样的东西

    distance city obs difference
    9        0    1   1
    5        1    2   0
    7        0    3   2
    6        0    4   1
    5        0    5   0
    10       1    6   0
    11       0    7   1
    15       0    8   5

其中新列中的第一个obs具有1,因为这是距离9和10之间的差,距离9和10是分别与观察值1和其最近的城市(在这种情况下为obs 6)关联的列距离值。相同的推理适用于其他对象。例如,obs 3的差异为2,因为这表示obs 3本身与其最接近的城市之间的列距离值之间的差异,在这种情况下为观察2。城市本身的差异为0。

有人可以帮我吗?

非常感谢。

2 个答案:

答案 0 :(得分:2)

这是一个dplyr解决方案,您可以在其中找到距任何城市的最小距离:

library(dplyr)
df %>% rowwise %>% mutate(difference = min(abs(df$distance[df$city == 1] - distance)))
#Source: local data frame [8 x 4]
#Groups: <by row>
#
# A tibble: 8 x 4
#  distance  city   obs difference
#     <int> <int> <int>      <int>
#1        9     0     1          1
#2        5     1     2          0
#3        7     0     3          2
#4        6     0     4          1
#5        5     0     5          0
#6       10     1     6          0
#7       11     0     7          1
#8       15     0     8          5

这是base-r方法:

df$difference <- sapply(df$distance,function(x)  min(abs(df$distance[df$city == 1] - x)))
df
#  distance city obs difference
#1        9    0   1          1
#2        5    1   2          0
#3        7    0   3          2
#4        6    0   4          1
#5        5    0   5          0
#6       10    1   6          0
#7       11    0   7          1
#8       15    0   8          5

答案 1 :(得分:2)

除了使用滚动连接外,这与@jasbner的相同,我怀疑在某些情况下可能会更有效:

library(data.table)
setDT(DF)

DF[, v := DF[city == 1][.SD, on=.(distance), roll="nearest", abs(x.distance-i.distance)]]

   distance city obs v
1:        9    0   1 1
2:        5    1   2 0
3:        7    0   3 2
4:        6    0   4 1
5:        5    0   5 0
6:       10    1   6 0
7:       11    0   7 1
8:       15    0   8 5