Home > Blockchain >  R data table aggregate data in some columns to list
R data table aggregate data in some columns to list

Time:04-05

I have csv file with next data:

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

Column with uniq key is person_id. Data is dublicated because in columns sample_number and label can by different data.

How can I aggregate data in this columns in list like bellow?

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

CodePudding user response:

data.table approach

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

CodePudding user response:

With tidyverse functions, group_by everything except label and sample_number and use 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

data

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=";")
  • Related