заменить элементы с шаблоном в кадре данных в r - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть один кадр данных, похожий на:

df1 = read.table(text="name element
    m20895  P540554
    m20897  S01367
    m20907  P540554,P209332
    m20914  S01367,S01247
    m20915  S01247
    m20925  S00897
    m26943  P540554,P209332
    m26944  S00897,S00898,S00899,S00900", header=T, stringsAsFactors=F)

Я хотел бы заменить любой элемент (элементы), начинающийся с "S", на соответствующее значение в столбце "B" кадра данных (df2)

    df2 = read.table(text="A    B
    S01367  P00432
    S01247  P00433
    S00897  P00434
    S00898  P00435
    S00899  P00436
    S00900  P00437
    S00901  P00438", header=T, stringsAsFactors=F)

, поэтому ожидаемый результат:

    result = read.table(text="name  element
    m20895  P540554
    m20897  P00432
    m20907  P540554,P209332
    m20914  P00432,P00433
    m20915  P00433
    m20925  P00434
    m26943  P540554,P209332
    m26944  P00434,P00435,P00436,P00437", header=T, stringsAsFactors=F)

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Вы также можете попробовать это

library(tidyverse)
df1 %>% 
  separate_rows(element) %>% 
  left_join(df2, by=c("element" = "A")) %>% 
  mutate(element = ifelse(is.na(B), element, B)) %>% 
  group_by(name) %>% 
  summarise(element= paste(element, collapse = ","))  
# A tibble: 8 x 2
  name   element                    
  <chr>  <chr>                      
1 m20895 P540554                    
2 m20897 P00432                     
3 m20907 P540554,P209332            
4 m20914 P00432,P00433              
5 m20915 P00433                     
6 m20925 P00434                     
7 m26943 P540554,P209332            
8 m26944 P00434,P00435,P00436,P00437
0 голосов
/ 06 декабря 2018

Сначала вам нужно разделить столбец element на ,:

element_split <- strsplit(df1$element, ",")

Вы получаете список, и для каждого элемента этого списка вы можете искать элемент, начинающийся с S(grep("^S", ...)) и замените их соответствующим значением B в вашем df2 (если его нет, то вы просто возвращаете элемент как есть):

l_element_B <- lapply(element_split, 
                      function(x) if(any(y <- grep("^S", x))) {x[y] <- df2$B[match(x[y], df2$A)]; x} else x)

Затем вы можете свернуть свойэлементы с ,, чтобы получить новый столбец (или сохранить его в виде списка, чтобы с ним было легче работать):

df1$new_element <- sapply(l_element_B, paste, collapse=",")

df1
#    name                     element                 new_element
#1 m20895                     P540554                     P540554
#2 m20897                      S01367                      P00432
#3 m20907             P540554,P209332             P540554,P209332
#4 m20914               S01367,S01247               P00432,P00433
#5 m20915                      S01247                      P00433
#6 m20925                      S00897                      P00434
#7 m26943             P540554,P209332             P540554,P209332
#8 m26944 S00897,S00898,S00899,S00900 P00434,P00435,P00436,P00437

NB:

Конечно, вы можете напрямую изменить столбец, выполнив

df1$element <- sapply(l_element_B, paste, collapse=",")

вместо

df1$new_element <- sapply(l_element_B, paste, collapse=",")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...