#r #compare
#r #Сравнить
Вопрос:
Я хочу сравнивать символы итеративно и возвращать несоответствия между 2 столбцами фрейма данных.
Он не должен возвращаться, если x2x, y67y, поскольку x остается x, а y остается как y .
Ввод:
x y x_val y_val
A B x2x, y67h, d7j x2y, y67y, d7r
B C x2y, y67y, d7r x2y, y67y, d7r
C A x2y, y67y, d7r x2x, y67h, d7j
C D x2y, y67y, d7r x67b, g72v, b8c
D E x67b, g72v, b8c x67r, g72j
Я хочу добавить столбец val и возвращать различия между x_val и y_val
Вывод:
x y x_val y_val val
A B x2x, y67h, d7j x2y, y67y, d7r x2y, d7r
B C x2y, y67y, d7r x2y, y67y, d7r NA
C A x2y, y67y, d7r x2x, y67h, d7j y67h, d7j
C D x2y, y67y, d7r y67b, g72v, b8c y67b, g72v, b8c
D E y67b, g72v, b8c y67b, g72j g72j
Я пытался xy_val <- y_val[!(y_val %in% x_val)]
Не могли бы вы, пожалуйста, предложить решение о том, как выводить несоответствия.
Мои данные:
structure(list(x = c("A", "B", "C", "C", "D"), y = c("B", "C", "A", "D", "E"), x_val = c("x2x, y67h, d7j", "x2y, y67y, d7r", "x2y, y67y, d7r", "x2y, y67y, d7r", "y67b, g72v, b8c"), y_val = c("x2y, y67y, d7r", "x2y, y67y, d7r", "x2x, y67h, d7j", "y67b, g72v, b8c", "y67b, g72j" )), class = "data.frame", row.names = c(NA, -5L))
Я ценю вашу помощь!
Спасибо
Комментарии:
1. Можете ли вы добавить свои данные в
dput(mydata)
форму? Не совсем ясно, каков формат ваших переменныхx_val
иy_val
. Это строки, разделенные запятыми? или векторы?2. Полезно знать, но я не спрашиваю о том, что представляют данные. Я спрашиваю о формате самих данных. «строки», как в строковых литералах в программировании.
3. f <- data.frame( x = c(«A», «B», «C», «C», «D»), y = c(«B», «C», «A», «D», «E»), x_val = c(«x2x, y67h, d7j», «x2y, y67y, d7r», «x2y, y67y, d7r», «x2y, y67y, y67y , d7r», «y67b, g72v, b8c»), y_val = c («x2y, y67y, d7r», «x2y, y67y, d7r», «x2x, y67h, d7j», «y67b, g72v, b8c», «y67b, g72j»))
4. структура (список(x = c(«A», «B», «C», «C», «D»), y = c(«B», «C», «A», «D», «E»), x_val = c(«x2x, y67h, d7j», «x2y, y67y, d7r», «x2y, y67y, d7r», «x2y, y67y, d7r», «y67b, g72v, b8c»), y_val = c («x2y, y67y, d7r», «x2y, y67y, d7r», «x2x, y67h, d7j», «y67b, g72v, b8c», «y67b, g72j»)), класс = «data.frame», row.names = c(NA, -5L))
5. Кто-нибудь может любезно помочь. Приведенный ниже код помогает, но он также не должен возвращать x2x, y67y, поскольку изменений нет.
Ответ №1:
С помощью dplyr
и purrr
:
library(dplyr)
library(purrr)
f %>% mutate(diff_x = map2_chr(strsplit(x_val, split = ", "),
strsplit(y_val, split = ", "),
~paste(grep('([a-z])(?>\d )(?!\1)', setdiff(.x, .y),
value = TRUE, perl = TRUE),
collapse = ", ")) %>%
replace(. == "", NA),
diff_y = map2_chr(strsplit(x_val, split = ", "),
strsplit(y_val, split = ", "),
~paste(grep('([a-z])(?>\d )(?!\1)', setdiff(.y, .x),
value = TRUE, perl = TRUE),
collapse = ", ")) %>%
replace(. == "", NA))
Примечания:
-
grep
принимает выходные данныеsetdiff
и удаляет любой элемент с форматом «одинаковые символы с цифрами между ними» -
([a-z])
соответствует любым буквенным символам. -
(?>\d )
это атомарная группа, которая сопоставляет цифры любой длины, но не выполняет обратный отсчет. -
(?!\1)
является отрицательным прогнозом, который соответствует тому, что было сопоставлено с([a-z])
Вывод:
x y x_val y_val diff_x diff_y
1 A B x2x, y67h, d7j x2y, y67y, d7r y67h, d7j x2y, d7r
2 B C x2y, y67y, d7r x2y, y67y, d7r <NA> <NA>
3 C A x2y, y67y, d7r x2x, y67h, d7j x2y, d7r y67h, d7j
4 C D x2y, y67y, d7r y67b, g72v, b8c x2y, d7r y67b, g72v, b8c
5 D E y67b, g72v, b8c y67b, g72j g72v, b8c g72j
Комментарии:
1. Когда я пытаюсь сохранить это как X, значения в diff_x и diff_y сохраняются в виде списка. X <- f %>% mutate(diff_x = map2(strsplit(x_val, split = «, «), strsplit(y_val, split = «, «), setdiff), diff_y = map2(strsplit(y_val, split = «, «), strsplit(x_val, split = «, «), setdiff))
2. Спасибо за обновление. Но я получаю следующую ошибку. Ошибка в strsplit(x_val, split = «, «): объект ‘x_val’ не найден
3. Разобрался, это должно быть f %>% вместо <- . Я ценю вашу помощь!
4. Извините, я забыл упомянуть, несоответствия не должны быть возвращены, если x2x (без изменений — нет мутации), как я показал это в выходных данных 3-го столбца: y67h, d7j [C A x2y, y67y, d7r x2x, y67h, d7j y67h, d7j] Не могли бы вы, пожалуйста, помочь мне с этим @avid_useR. Спасибо
5. @sdu Мы можем добавить
grep
insidepaste
, чтобы удалить любые строки с форматом «одинаковые символы с цифрами между ними»
Ответ №2:
дает ли это желаемые результаты?
check_this = function(temp_data)
{
print(temp_data)
string_1 = gsub(", ", " ", temp_data["x_val"])
string_2 = gsub(", ", " ", temp_data["y_val"])
string_sub_1 = gsub(" ", "|", string_1)
string_sub_2 = gsub(" ", "|", string_2)
unmatche_s1 = gsub(string_sub_2, "", string_1)
unmatche_s2 = gsub(string_sub_1, "", string_2)
# return both as a list - if you need only unmachtedy_in_x you can just return(unmatched_s2)
return(list(unmatchedx_in_y = unmatche_s1, unmatchedy_in_x = unmatche_s2))
}
res = apply(f, 1, check_this)