【问题标题】:Operation along the same column given a logical condition给定逻辑条件沿同一列的操作
【发布时间】:2018-11-13 21:18:48
【问题描述】:

我有一个这种形式的数据框

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

我想创建一个新列“difference”,它计算每个观察值与其最近(就列距离中的值而言)城市之间的“距离”列中的值的差异。

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

    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 之间的差异,它们分别是与观察 1 及其最近的城市(在本例中为 obs 6)相关的列距离中的值。相同的推理适用于其他 obs。例如,obs 3 表示差异为 2,因为这表示 obs 3 本身与其最近的城市之间的列距离值之间的差异,在这种情况下是观察 2。城市本身存在 0。

谁能帮我解决这个问题?

非常感谢。

【问题讨论】:

    标签: r


    【解决方案1】:

    这是一个 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
    

    【讨论】:

    • 非常感谢 jasbner。真的很感激。
    【解决方案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
    

    【讨论】:

    猜你喜欢
    • 2015-10-27
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    • 2021-06-23
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    • 1970-01-01
    相关资源
    最近更新 更多