行绑定数据框并保持唯一 ID 递增

Row bind dataframes and keep unique IDs incrementing

我有 2 个数据集要叠加在一起。请注意,第一个数据集的 record_ids 也从 1

开始
record_id       any_column
     591             a
     591             b
     591             c
     592             d
     592             e
     592             f
     592             g
     593             h
     593             i
     593             j

第二个数据集

record_id       any_column
     1             a
     1             b
     1             c
     2             d
     2             e
     2             f
     2             g
     3             h
     3             i
     3             j 

当堆叠时,我希望第二个数据集的 record_ids 从第一个数据集的 recod_ids 立即结束的地方开始,在这种情况下 593,我想将第二个数据集的 ID 转换为以 594 开头的内容,依此类推。我怎样才能最好地解决这个问题?谢谢

对未来数据集的预期如下:

record_id       any_column        grand_id
     591             a               591
     591             b               591
     591             c               591
     592             d               592
     592             e               592
     592             f               592
     592             g               592
     593             h               593
     593             i               593
     593             j               593
     1             a                 594
     1             b                 594
     1             c                 594
     2             d                 595
     2             e                 595
     2             f                 595
     2             g                 595
     3             h                 596
     3             i                 596
     3             j                 596 

我认为你应该在第一个数据集结束时使用 if 语句,只需保存最后一个值索引并递增它,不要忘记检查第二个数据集记录 ID 是否相似

您可以从 df1 中获得 record_id 中的 max 并添加到 df2 中的 record_id

rbind(transform(df1, grand_id = record_id), 
      transform(df2, grand_id = record_id + max(df1$record_id)))

如果你喜欢 dplyr :

library(dplyr)

df1 %>%
  mutate(grand_id = record_id) %>%
  bind_rows(df2 %>% mutate(grand_id = record_id + max(df1$record_id)))

#   record_id any_column grand_id
#1        591          a      591
#2        591          b      591
#3        591          c      591
#4        592          d      592
#5        592          e      592
#6        592          f      592
#7        592          g      592
#8        593          h      593
#9        593          i      593
#10       593          j      593
#11         1          a      594
#12         1          b      594
#13         1          c      594
#14         2          d      595
#15         2          e      595
#16         2          f      595
#17         2          g      595
#18         3          h      596
#19         3          i      596
#20         3          j      596

顶级数据集的id值可以改变吗?如果是这样,另一种选择是使用 dplyr::dense_rank()。这可能更容易泛化到两个以上的数据集。它将保留输入数据集内部和之间的相对顺序

ds_stack <- 
  ds_top %>% 
  # dplyr::union_all(ds_middle) %>% # Add more datasets in here if necessary
  dplyr::union_all(ds_bottom) %>% 
  dplyr::mutate(
    grand_id = dplyr::dense_rank(paste0(source, "-", record_id))
  )

# # A tibble: 20 x 4
#       record_id any_column source grand_id
#       <int> <chr>       <int>    <int>
# 1       591 a               1        1
# 2       591 b               1        1
# 3       591 c               1        1
# 4       592 d               1        2
# 5       592 e               1        2
# 6       592 f               1        2
# 7       592 g               1        2
# 8       593 h               1        3
# 9       593 i               1        3
# 10      593 j               1        3
# 11        1 a               2        4
# 12        1 b               2        4
# 13        1 c               2        4
# 14        2 d               2        5
# 15        2 e               2        5
# 16        2 f               2        5
# 17        2 g               2        5
# 18        3 h               2        6
# 19        3 i               2        6
# 20        3 j               2        6

输入数据集:

library("magrittr")
ds_top <- 
  tibble::tribble(
    ~record_id, ~any_column,
    591L,"a",
    591L,"b",
    591L,"c",
    592L,"d",
    592L,"e",
    592L,"f",
    592L,"g",
    593L,"h",
    593L,"i",
    593L,"j"
  ) %>% 
  dplyr::mutate(
    source = 1L
  )

ds_bottom <- 
  tibble::tribble(
    ~record_id, ~any_column,
    1L, "a",
    1L, "b",
    1L, "c",
    2L, "d",
    2L, "e",
    2L, "f",
    2L, "g",
    3L, "h",
    3L, "i",
    3L, "j"
  ) %>% 
  dplyr::mutate(
    source = 2L
  )

这里有一个 的细微变化,可以推广到任意数量的输入数据集。由于您不计算输入数据集的数量,因此您将无法对固定数量的 dplyr::union_all() 调用进行硬编码。

如果输入数据集是名为 l 的列表中的元素,则 purrr::map_dfr() 会隐式处理 union

l %>% 
  purrr::map_df(~.) %>% 
  dplyr::mutate(
    grand_id = dplyr::dense_rank(paste0(source, "-", record_id))
  )
# # A tibble: 15 x 4
#   source record_id any_column grand_id
#    <int>     <int> <chr>         <int>
# 1      1       591 a                 1
# 2      1       591 b                 1
# 3      1       592 c                 2
# 4      1       592 d                 2
# 5      1       593 e                 3
# 6      2         1 a                 4
# 7      2         1 b                 4
# 8      2         2 c                 5
# 9      2         2 d                 5
# 10     2         3 e                 6
# 11     3         1 f                 7
# 12     3         1 g                 7
# 13     3         2 h                 8
# 14     3         3 i                 9
# 15     3         3 j                 9

在这种情况下,数据集可能来自各种 similarly-structured 数据库,这些数据库本质上会产生

library("magrittr")
ds_top <- 
  tibble::tribble(
    ~source, ~record_id, ~any_column,
    1L, 591L,"a",
    1L, 591L,"b",
    1L, 592L,"c",
    1L, 592L,"d",
    1L, 593L,"e"
  )

ds_middle <- 
  tibble::tribble(
    ~source, ~record_id, ~any_column,
    2L, 1L, "a",
    2L, 1L, "b",
    2L, 2L, "c",
    2L, 2L, "d",
    2L, 3L, "e"
  )

ds_bottom <- 
  tibble::tribble(
    ~source, ~record_id, ~any_column,
    3L, 1L, "f",
    3L, 1L, "g",
    3L, 2L, "h",
    3L, 3L, "i",
    3L, 3L, "j"
  )
l <- list(ds_top, ds_middle, ds_bottom)

但是如果你从 identically-structured csv 文件中提取,一些操作可以像

ds_stack <-
  vector_of_file_paths %>%
  purrr::map_dfr(~readr:read_csv(.), .id = "source") %>% 
  dplyr::mutate(
    grand_id = dplyr::dense_rank(paste0(source, "-", record_id))
  )