R data table 汇总某些列中的数据以列出

R data table aggregate data in some columns to list

我有包含下一个数据的 csv 文件:

person_id;first_name;birth_date;gender;sample_number;label
1;Ann;01.01.1977;1;MID43;PrBadMedian
1;Ann;01.01.1977;1;MID43;IB15
1;Ann;01.01.1977;1;Center1577;PrBadMedian
1;Ann;01.01.1977;1;Center1577;IB15
2;Kate;01.01.1989;1;MID55;PrBadMedian
2;Kate;01.01.1989;1;MID55;IB15
2;Kate;01.01.1989;1;Center3127;PrBadMedian
2;Kate;01.01.1989;1;Center3127;IB15
3;Jane;01.01.1991;1;MID78;PrBadMedian
3;Jane;01.01.1991;1;MID78;IB15

具有唯一键的列是 person_id。数据是重复的,因为在列 sample_numberlabel 中可以使用不同的数据。

如何汇总列表中此列中的数据,如下所示?

person_id;first_name;birth_date;gender;sample_number;label
1;Ann;01.01.1977;1;MID43,Center1577;PrBadMedian,IB15
2;Kate;01.01.1989;1;MID55,Center3127;PrBadMedian,IB15
3;Jane;01.01.1991;1;MID78;PrBadMedian,IB15

使用 tidyverse 函数,group_bylabelsample_number 之外的所有内容,并使用 summarise:

library(tidyverse)

df %>% 
  group_by(across(-c(sample_number, label))) %>% 
  summarise(across(c(sample_number, label), ~ paste(unique(.x), collapse = ",")))

# A tibble: 3 x 6
# Groups:   person_id, first_name, birth_date [3]
  person_id first_name birth_date gender sample_number    label           
      <int> <chr>      <chr>       <int> <chr>            <chr>           
1         1 Ann        01.01.1977      1 MID43,Center1577 PrBadMedian,IB15
2         2 Kate       01.01.1989      1 MID55,Center3127 PrBadMedian,IB15
3         3 Jane       01.01.1991      1 MID78            PrBadMedian,IB15

数据

df <- read.table(header = T, text = "person_id;first_name;birth_date;gender;sample_number;label
1;Ann;01.01.1977;1;MID43;PrBadMedian
1;Ann;01.01.1977;1;MID43;IB15
1;Ann;01.01.1977;1;Center1577;PrBadMedian
1;Ann;01.01.1977;1;Center1577;IB15
2;Kate;01.01.1989;1;MID55;PrBadMedian
2;Kate;01.01.1989;1;MID55;IB15
2;Kate;01.01.1989;1;Center3127;PrBadMedian
2;Kate;01.01.1989;1;Center3127;IB15
3;Jane;01.01.1991;1;MID78;PrBadMedian
3;Jane;01.01.1991;1;MID78;IB15", sep=";")

data.table接近

library(data.table)

DT <- fread("person_id;first_name;birth_date;gender;sample_number;label
            1;Ann;01.01.1977;1;MID43;PrBadMedian
            1;Ann;01.01.1977;1;MID43;IB15
            1;Ann;01.01.1977;1;Center1577;PrBadMedian
            1;Ann;01.01.1977;1;Center1577;IB15
            2;Kate;01.01.1989;1;MID55;PrBadMedian
            2;Kate;01.01.1989;1;MID55;IB15
            2;Kate;01.01.1989;1;Center3127;PrBadMedian
            2;Kate;01.01.1989;1;Center3127;IB15
            3;Jane;01.01.1991;1;MID78;PrBadMedian
            3;Jane;01.01.1991;1;MID78;IB15")

DT[, lapply(.SD, function(x) paste0(unique(x), collapse=",")), 
   by = .(person_id, first_name, birth_date, gender)]

# person_id first_name birth_date gender    sample_number            label
# 1:         1        Ann 01.01.1977      1 MID43,Center1577 PrBadMedian,IB15
# 2:         2       Kate 01.01.1989      1 MID55,Center3127 PrBadMedian,IB15
# 3:         3       Jane 01.01.1991      1            MID78 PrBadMedian,IB15