Для каждого идентификатора разделите группы на столбцы и сверните несколько строк значений в R - PullRequest
0 голосов
/ 11 января 2020

У меня есть кадр данных, который выглядит следующим образом:

in.dat <- data.frame(ID = c("A1", "A1", "A1", "A1", "B1", "B1", "B1", "B1"),
           DB = rep(c("bio", "bio", "func", "loc"), 2),
           val = c("IPR1", "IPR2", "s43", "333-456", 
                   "IPR7", "IPR8", "q87", "566-900"))

  ID   DB     val
1 A1  bio    IPR1
2 A1  bio    IPR2
3 A1 func     s43
4 A1  loc 333-456
5 B1  bio    IPR7
6 B1  bio    IPR8
7 B1 func     q87
8 B1  loc 566-900

Я хочу превратить «БД» в столбцы, взять строковые значения и свернуть на «;»

out.dat <- data.frame(ID = c("A1", "B1"),
                  bio = c("IPR1;IPR2", "IPR7;IPR8"),
                  func = c("s47", "q87"),
                  loc = c("333-456", "566-900"))

> out
  ID       bio func     loc
1 A1 IPR1;IPR2  s47 333-456
2 B1 IPR7;IPR8  q87 566-900

Я играл с pivot_wider и group, используя dplyr, но не совсем получая то, что хочу, так как у группы может быть несколько значений для каждого идентификатора, который я хочу свернуть в одну ячейку (например, «IPR1; IPR2») )

Любое решение будет оценено!

Ответы [ 4 ]

0 голосов
/ 11 января 2020

pivot_wider в последних tidyr версиях принимает аргумент values_fn для функции, которая агрегирует значения перед изменением формы. Это позволяет вам выполнить операцию за один вызов функции.

library(tidyr)

in.dat %>%
  pivot_wider(names_from = DB, values_from = val, 
              values_fn = list(val = ~paste(., collapse = ";")))
#> # A tibble: 2 x 4
#>   ID    bio       func  loc    
#>   <fct> <chr>     <chr> <chr>  
#> 1 A1    IPR1;IPR2 s43   333-456
#> 2 B1    IPR7;IPR8 q87   566-900
0 голосов
/ 11 января 2020

Вы можете использовать dcast для этого.

in.dat <- data.frame(ID = c("A1", "A1", "A1", "A1", "B1", "B1", "B1", "B1"),
                     DB = rep(c("bio", "bio", "func", "loc"), 2),
                     val = c("IPR1", "IPR2", "s43", "333-456", 
                             "IPR7", "IPR8", "q87", "566-900"))

library(reshape2)
dcast(in.dat, ID ~ DB, paste0, collapse = ";")
#  ID       bio func     loc
#1 A1 IPR1;IPR2  s43 333-456
#2 B1 IPR7;IPR8  q87 566-900
0 голосов
/ 11 января 2020

Мы также можем использовать spread с str_c

library(dplyr)
library(tidyr)
library(stringr)
in.dat %>% 
   group_by(ID, DB) %>% 
   summarise(val = str_c(val, collapse=";")) %>% 
   spread(DB, val)
# A tibble: 2 x 4
# Groups:   ID [2]
#   ID    bio       func  loc    
#   <fct> <chr>     <chr> <chr>  
#1 A1    IPR1;IPR2 s43   333-456
#2 B1    IPR7;IPR8 q87   566-900
0 голосов
/ 11 января 2020

Мы можем свернуть val на ID и DB, а затем использовать pivot_wider.

library(dplyr)

in.dat %>%
  group_by(ID, DB) %>%
  summarise(val = paste0(val, collapse = ";")) %>%
  tidyr::pivot_wider(names_from = DB, values_from = val)

#  ID    bio       func  loc    
#  <fct> <chr>     <chr> <chr>  
#1 A1    IPR1;IPR2 s43   333-456
#2 B1    IPR7;IPR8 q87   566-900
...