我有这种形式的数据框
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。
有人可以帮我吗?
非常感谢。
答案 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