#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=",")