【问题标题】:Add unique ID column based on values in two other columns (lat, long)根据其他两列(纬度、经度)中的值添加唯一 ID 列
【发布时间】:2021-05-26 20:30:15
【问题描述】:

已提出此问题,但我正在寻找更完整的答案/稍作修改的输出。

我有一个数据集,其 Lat 和 Long 值分别位于不同的列中,并希望为 Lat 和 Long 的每个唯一组合创建一个唯一 ID。

我将借用一个较早的帖子中的示例数据集,提出相同的问题,但我需要稍微不同的解决方案 (Add ID column by group)。

d <- read.table(text='LAT LONG
13.5330 -15.4180 
13.5330 -15.4180 
13.5330 -15.4180 
13.5330 -15.4180 
13.5330 -15.4170 
13.5330 -15.4170 
13.5330 -15.4170 
13.5340 -14.9350 
13.5340 -14.9350 
13.5340 -15.9170 
13.3670 -14.6190', header=TRUE)

给出的解决方案是:

d <- transform(d, Cluster_ID = as.numeric(interaction(LAT, LONG, drop=TRUE)))

#       LAT    LONG Cluster_ID
# 1  13.533 -15.418          2
# 2  13.533 -15.418          2
# 3  13.533 -15.418          2
# 4  13.533 -15.418          2
# 5  13.533 -15.417          3
# 6  13.533 -15.417          3
# 7  13.533 -15.417          3
# 8  13.534 -14.935          4
# 9  13.534 -14.935          4
# 10 13.534 -15.917          1
# 11 13.367 -14.619          5

但是如何让interaction 命令保留顺序,以便上面的第一个 Cluster_ID 为 1(最后一列的完整向量为 1,1,1,1,2,2,2,3,3 ,4,5 而不是 2,2,2,2,3,3,4,4,1,5)?目前尚不清楚新的因子顺序(转换为数字)是如何确定的。

我也一直在尝试使用 dplyr 中的 group_by 找到等效的方法,但无法弄清楚如何将 tibble 表输出为数据框(SO 上的旧解决方案似乎使用了已弃用的 dplyr 命令) .

谢谢!

【问题讨论】:

    标签: r dataframe grouping unique


    【解决方案1】:

    我们可以使用match

    transform(d, Cluster_ID = match(paste0(LAT, LONG), unique(paste0(LAT, LONG))))
    

    或将“LAT”、“LONG”转换为序列,然后执行interaction

    transform(d, Cluster_ID = as.integer(interaction(match(LAT, 
      unique(LAT)),  match(LONG, unique(LONG)), drop=TRUE, lex.order = FALSE)))
    

    【讨论】:

    • 感谢@akrun,使用匹配转换为序列效果很好!
    【解决方案2】:

    使用.GRPdata.table 选项

    > setDT(d)[, Cluster_ID := .GRP, .(LAT, LONG)][]
           LAT    LONG Cluster_ID
     1: 13.533 -15.418          1
     2: 13.533 -15.418          1
     3: 13.533 -15.418          1
     4: 13.533 -15.418          1
     5: 13.533 -15.417          2
     6: 13.533 -15.417          2
     7: 13.533 -15.417          2
     8: 13.534 -14.935          3
     9: 13.534 -14.935          3
    10: 13.534 -15.917          4
    11: 13.367 -14.619          5
    

    rleid(感谢@akrun 的评论)

    > setDT(d)[, Cluster_ID := rleid(LAT, LONG)][]
           LAT    LONG Cluster_ID
     1: 13.533 -15.418          1
     2: 13.533 -15.418          1
     3: 13.533 -15.418          1
     4: 13.533 -15.418          1
     5: 13.533 -15.417          2
     6: 13.533 -15.417          2
     7: 13.533 -15.417          2
     8: 13.534 -14.935          3
     9: 13.534 -14.935          3
    10: 13.534 -15.917          4
    11: 13.367 -14.619          5
    

    或使用ave + cumsum 的基本 R 选项

    transform(
      d,
      Cluster_ID = cumsum(
        ave(1:nrow(d),
          LAT,
          LONG,
          FUN = seq_along
        ) == 1
      )
    )
    

    【讨论】:

      猜你喜欢
      • 2015-10-10
      • 1970-01-01
      • 2017-11-21
      • 2023-03-09
      • 2022-12-17
      • 2015-05-30
      • 2016-09-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多