Сравнить любое значение столбца A с любым значением в столбце B

#r

#r

Вопрос:

Я хочу сравнить два столбца:

столбец A:

 IGHV3-21*02,IGHV3-30-5*04    
IGHV3-30*18,IGHV3-30-5*01    
IGHV5-51*01    
IGHV5-76*01
 

столбец B:

 IGHV3-21*02  
IGHV3-30*18    
IGHV5-51*01
IGHV6-51*01
 

и сопоставить, соответствует ли какой-либо элемент в столбце A любому элементу столбца B (или наоборот)

Ожидаемый результат должен быть:

совпадение столбцов:

 TRUE  
TRUE  
TRUE  
FALSE  
 

в R самым простым способом может быть:

 df$columnA %in% df$columnB  
 

Но это не учитывает оба элемента в заданной позиции и вернет:

 FALSE  
FALSE  
TRUE  
FALSE  
 

Есть идеи, как обрабатывать слова, разделенные запятой, чтобы использовать%в%?

Ответ №1:

Работает ли это:

 library(dplyr)
library(tidyr)
library(stringr)
df %>% mutate(id = row_number()) %>% 
   separate_rows(columnA, sep = ',') %>% 
   mutate(match = columnA == columnB) %>% 
   group_by(id) %>% mutate(columnA = toString(columnA)) %>% 
   mutate(match = if_else(any(match == TRUE), TRUE, FALSE)) %>% 
   distinct() %>% ungroup() %>% select(-id)
# A tibble: 4 x 3
  columnA                    columnB     match
  <chr>                      <chr>       <lgl>
1 IGHV3-21*02, IGHV3-30-5*04 IGHV3-21*02 TRUE 
2 IGHV3-30*18, IGHV3-30-5*01 IGHV3-30*18 TRUE 
3 IGHV5-51*01                IGHV5-51*01 TRUE 
4 IGHV5-76*01                IGHV6-51*01 FALSE
 

Используемые данные:

 df
                    columnA     columnB
1 IGHV3-21*02,IGHV3-30-5*04 IGHV3-21*02
2 IGHV3-30*18,IGHV3-30-5*01 IGHV3-30*18
3               IGHV5-51*01 IGHV5-51*01
4               IGHV5-76*01 IGHV6-51*01
 

Комментарии:

1. это замечательно, что делать, если у меня больше 2 в столбце A и больше 2 в столбце B? потому что у меня тоже есть такие случаи…

2. @fusion.slope, я полагаю, вы имеете в виду, если бы у вас были значения, разделенные запятыми, как в A, так и в B. В этом случае вам также потребуется разделить строки для B и использовать ту же логику.

3. да, в A и / или B более 2 значений, разделенных запятыми, и по крайней мере одно из двух совпадает..

Ответ №2:

Может быть, это может быть полезно:

 library(tidyverse)
#Code
newdf <- df1 %>% mutate(id=row_number()) %>%
  separate_rows(V1,sep=',') %>% left_join(df2 %>% mutate(Match=T)) %>%
  group_by(id) %>%
  mutate(Val=ifelse(any(Match amp; !is.na(Match)),T,F)) %>%
  select(-Match) %>%
  summarise(V1=paste0(V1,collapse = ','),
            Val=sum(Val)) %>%
  mutate(Val=ifelse(Val>0,T,F)) %>%
  ungroup() %>% select(-id)
 

Вывод:

 # A tibble: 4 x 2
  V1                        Val  
  <chr>                     <lgl>
1 IGHV3-21*02,IGHV3-30-5*04 TRUE 
2 IGHV3-30*18,IGHV3-30-5*01 TRUE 
3 IGHV5-51*01               TRUE 
4 IGHV5-76*01               FALSE
 

Некоторые используемые данные:

 #Data1
df1 <- structure(list(V1 = c("IGHV3-21*02,IGHV3-30-5*04", "IGHV3-30*18,IGHV3-30-5*01", 
"IGHV5-51*01", "IGHV5-76*01")), class = "data.frame", row.names = c(NA, 
-4L))

#Data2
df2 <- structure(list(V1 = c("IGHV3-21*02", "IGHV3-30*18", "IGHV5-51*01", 
"IGHV6-51*01")), class = "data.frame", row.names = c(NA, -4L))
 

Ответ №3:

Взгляните на base::charmatch . Вот простая оболочка функции над ним.

 `%pin%` <- function(x, y) {
  out <- logical(length(x))
  p <- unique(charmatch(y, x, 0L))
  out[p[p > 0L]] <- TRUE
  out
}
 

Данные

 x <- c("IGHV3-21*02,IGHV3-30-5*04",
"IGHV3-30*18,IGHV3-30-5*01",
"IGHV5-51*01",
"IGHV5-76*01")

y <- c(
  "IGHV3-21*02",  
  "IGHV3-30*18",
  "IGHV5-51*01",
  "IGHV6-51*01"
)
 

Использование

 > x %pin% y
[1]  TRUE  TRUE  TRUE FALSE
 

Ответ №4:

Вы можете использовать tidyr , чтобы разбить строки с запятыми на разные строки:

 df1 <- df %>% separate_rows(columnA,sep=",")