Как найти идентификатор и поместить его в новый столбец - PullRequest
2 голосов
/ 15 января 2020

Я новичок в R и использую пакет Tidyverse

У меня есть такие данные

ID   Jobs    Successors
1    JobA    JobB;JobC
2    JobB    JobD
3    JobC    JobD
4    JobD

, и я хочу добавить столбец с идентификаторами наследников, чтобы данные смотреть лайки

ID   Jobs    Successors    SuccessorIds
1    JobA    JobB;JobC     2;3
2    JobB    JobD          4
3    JobC    JobD          4
4    JobD

Ответы [ 7 ]

5 голосов
/ 15 января 2020

str_replace_all() в stringr может заменить совпавшие шаблоны в строке. Преимущество состоит в том, что он может применять несколько шаблонов и замен к одной и той же строке, передавая с именем vector . Здесь я использую setNames() для создания именованного вектора, чтобы указать шаблоны и замены.

df %>%
  mutate(SuccessorIds = str_replace_all(Successors, setNames(as.character(ID), Jobs)))

#   ID Jobs Successors SuccessorIds
# 1  1 JobA  JobB;JobC          2;3
# 2  2 JobB       JobD            4
# 3  3 JobC       JobD            4
# 4  4 JobD       <NA>         <NA>
5 голосов
/ 15 января 2020

Один из вариантов, включающий dplyr и purrr, может быть:

df %>%
 mutate(SuccessorsIds = map(.x = strsplit(Successors, ";", fixed = TRUE),
                            ~ ID[match(.x, Jobs)]))

  ID Jobs Successors SuccessorsIds
1  1 JobA  JobB;JobC          2, 3
2  2 JobB       JobD             4
3  3 JobC       JobD             4
4  4 JobD       <NA>            NA

И если вам не нужен список, а символьный вектор:

df %>%
 mutate(SuccessorsIds = map_chr(.x = strsplit(Successors, ";", fixed = TRUE),
                                ~ paste0(ID[match(.x, Jobs)], collapse = ";")))

  ID Jobs Successors SuccessorsIds
1  1 JobA  JobB;JobC           2;3
2  2 JobB       JobD             4
3  3 JobC       JobD             4
4  4 JobD       <NA>            NA
3 голосов
/ 15 января 2020

Вот один из способов сделать это:

  • Создать таблицу поиска из заданий на идентификатор
  • Разделить преемников
  • Искать идентификаторы
  • Повторно присоединитесь с помощью ';'
library(tidyverse)
df = read_table('ID   Jobs    Successors
1    JobA    JobB;JobC
2    JobB    JobD
3    JobC    JobD
4    JobD')

# lookup for ID
id_lookup = df$ID %>% set_names(df$Jobs)

df$SuccessorIds = str_split(df$Successors, ';') %>% 
  map_chr(~id_lookup[.x] %>% paste(collapse=';'))
df
#> # A tibble: 4 x 4
#>      ID Jobs  Successors SuccessorIds
#>   <dbl> <chr> <chr>      <chr>       
#> 1     1 JobA  JobB;JobC  2;3         
#> 2     2 JobB  JobD       4           
#> 3     3 JobC  JobD       4           
#> 4     4 JobD  <NA>       NA

Создано в 2020-01-15 с помощью пакета prex (v0.3.0)

2 голосов
/ 15 января 2020

Вот базовое решение R с использованием strsplit() + match()

df$SuccessorsIds <- apply(df, 1, function(v) paste0(match(unlist(strsplit(v["Successors"],split = ";")),df$Jobs),collapse = ";"))

таким, что

> df
  ID Jobs Successors SuccessorsIds
1  1 JobA  JobB;JobC           2;3
2  2 JobB       JobD             4
3  3 JobC       JobD             4
4  4 JobD       <NA>            NA
2 голосов
/ 15 января 2020

Мы можем использовать separate_rows из tidyr, чтобы разделить данные на разные строки на основе ";", match Successors и Jobs, чтобы получить соответствующие ID, group_by ID и Jobs и вставьте данные.

library(dplyr)
df %>%
  tidyr::separate_rows(Successors, sep = ";") %>%
  mutate(SuccessorIds = ID[match(Successors, Jobs)]) %>%
  group_by(ID, Jobs) %>%
  summarise_at(vars(Successors, SuccessorIds), paste0, collapse = ";")


#    ID Jobs  Successors SuccessorIds
#  <int> <fct> <chr>      <chr>       
#1     1 JobA  JobB;JobC  2;3         
#2     2 JobB  JobD       4           
#3     3 JobC  JobD       4           
#4     4 JobD  NA         NA          

данные

df <- structure(list(ID = 1:4, Jobs = structure(1:4, .Label = c("JobA", 
"JobB", "JobC", "JobD"), class = "factor"), Successors = structure(c(1L, 
2L, 2L, NA), .Label = c("JobB;JobC", "JobD"), class = "factor")), 
class = "data.frame", row.names = c(NA, -4L))
1 голос
/ 15 января 2020

Мы можем сделать это легко с gsubfn

library(gsubfn)
df$SuccessorIds <- gsubfn("(\\w+)", setNames(as.list(df$ID),df$Jobs), df$Successors)
df
#   ID Jobs Successors SuccessorIds
#1  1 JobA  JobB;JobC          2;3
#2  2 JobB       JobD            4
#3  3 JobC       JobD            4
#4  4 JobD       <NA>           NA

data

df <- structure(list(ID = 1:4, Jobs = c("JobA", "JobB", "JobC", "JobD"
), Successors = c("JobB;JobC", "JobD", "JobD", NA)), row.names = c(NA, 
-4L), class = "data.frame")
0 голосов
/ 15 января 2020

Это многословно, но разделение на ";", самостоятельное объединение и свертывание снова кажется гибким и (по крайней мере, как я думаю и работаю) довольно разборчивым.

library(dplyr)

df %>%
  tidyr::separate_rows(Successors, sep = ";") %>%
  left_join(x = ., y = ., by = c("Successors" = "Jobs")) %>%
  select(ID = ID.x, Jobs, Successors, SuccessorsIds = ID.y) %>%
  group_by(ID, Jobs) %>%
  summarise_at(vars(Successors, SuccessorsIds), paste, collapse = ";")
#> # A tibble: 4 x 4
#> # Groups:   ID [4]
#>      ID Jobs  Successors SuccessorsIds
#>   <dbl> <chr> <chr>      <chr>        
#> 1     1 JobA  JobB;JobC  2;3          
#> 2     2 JobB  JobD       4            
#> 3     3 JobC  JobD       4            
#> 4     4 JobD  NA         NA
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...