Создать двоичную переменную C при условии частичного совпадения между столбцами A и B

#r

#r

Вопрос:

Я хотел бы создать двоичную переменную C при условии 1 или более совпадений между записями в переменных A и B. Таким образом, в случае A, запись строки 1 «123» равна 3 отдельным записям «1,2,3», и если B содержит хотя бы одно из этих чисел, то столбецC будет содержать «1» для совпадения 1 .

Все записи содержат целые числа 1-10 для каждой строки в A и B. итак, что-то еще, что мне нужно сделать, это убедиться, что код не совпадает между 1 и 10.

ie: 104=»10,4″; 1345=»1,3,4,5″, итак, 1 и 10 — это разные записи, которые я не хочу путать с совпадением.

 A: 123, 345, 259, 459, 104

B: 134, 452, 349, 594, 391

C: 1, 1, 1, 1, 0
  

Я пробовал str_detect пакета stringr, а также purr(), но в них отсутствуют несколько записей, которые имеют совпадающие целые числа:

 A: 123, 345, 259, 459, 104

B: 134, 452, 349, 594, 391

df = df %>% 
  dplyr::mutate(C = purrr::map2_dbl(.x=A,.y=B,~ifelse(grepl(.y,.x),1,0)))
  

что дает результат:

 C: 0, 0, 1, 0, 0
  

по сути, он кодирует «0» для значений соответствия, которые не выровнены в одной позиции…

есть предложения, как это исправить?? я пробовал функцию any(), но она не работает.

Ответ №1:

Решение, основанное на tidyverse, может выглядеть следующим образом.

 library(dplyr)
library(stringr)
library(purrr)

data %>%
  mutate(Ax = map_chr(str_extract_all(A, str_c(10:1, collapse = '|')),
                      ~ str_c(.x, collapse = '|')),
         C =  str_detect(B, Ax)) %>%
  select(-Ax)

#       A     B     C
#   <dbl> <dbl> <int>
# 1   123   134     1
# 2   345   452     1
# 3   259   349     1
# 4   459   594     1
# 5   104   391     0
  

Данные

 data <- structure(list(A = c(123, 345, 259, 459, 104), B = c(134, 452, 
349, 594, 391)), row.names = c(NA, -5L), class = c("tbl_df", 
"tbl", "data.frame"))
  

Допустив длинную строку, мы могли бы поместить создание Ax в создание C (что избавило бы нас от строк из mutate(Ax и select(-Ax) . Это также будет работать лучше. Но это будет читаться менее хорошо.

Начиная изнутри и двигаясь наружу, str_c(10:1, collapse = '|') дает нам '10|9|8...|1' . Порядок убывания гарантирует, что 10 она будет сопоставлена раньше 1 . str_extract_all() используется '10|9|8...|1' для отображения совпадений из A списка векторов. map_chr() сворачивает векторы внутри списка и возвращает символьный вектор Ax с Ax[1] помощью as '1|2|3' . Ax затем используется внутри str_detect() для предоставления вектора bools ( C ), указывающего на наличие одного или нескольких элементов из записей Ax in B . преобразует C из TRUE-FALSE в 1-0 .

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

1. вау, спасибо, работает отлично! не могли бы вы объяснить логику решения только для дальнейшего использования?

2. @hongpastry: С удовольствием. Я добавил немного объяснений к своему сообщению.