#r
#r
Вопрос:
Я пытаюсь использовать R для создания функции, которая принимает два списка в качестве входных данных и возвращает общие элементы, но без использования функции intersect. Я все еще борюсь с некоторыми вещами, когда изучаю R:
- списки против векторов против фреймов данных
- как сохранить / сохранить результаты из циклов и функций for
- как использовать sapply / mapply / etc.
Вот что у меня есть на данный момент. Сначала я думал, что это сработало, когда единственным общим элементом было ‘5’, но когда я добавил более общие числа, он по-прежнему возвращает только ‘5’.
** Примечание — после написания этого я понял, что необходимо запускать это только в одном направлении (есть ли что-нибудь в list_a также в list_b), но теперь мне любопытно, как запустить эту версию с точки зрения программирования.
a <- list(1,2,3,4,5)
b <- list(3,4,5,6,7,8,9,10,11)
a_match <- numeric()
b_match <- numeric()
ab <- function(list_a, list_b) {
for (i in list_a) {
results <- if(i %in% list_b) {i}
a_in_b <- c(a_match, results)
}
for (i in list_b) {
results <- if(i %in% list_a) {i}
b_in_a <- c(b_match, results)
}
combined <- c(a_in_b, b_in_a)
unique(combined)
}
ab(a, b)
Есть ли способ использовать ‘apply’ здесь? и:
- возвращает вектор, длина которого отличается от длины входных данных (ограничение sapply)
- может принимать несколько входных данных разной длины (ограничение отображения)
Комментарии:
1. вы имеете дело с наборами?? например
a<- list(3, 4, list(1,2)
, иb<- list(4, list(2,1), 3)
будете ли вы считать эти два эквивалентными?? по умолчанию они
Ответ №1:
Ваши a_match и b_match находятся вне объявленных вне функции. Я исправил ваш пример проверки ниже:
a <- list(1,2,3,4,5)
b <- list(3,4,5,6,7,8,9,10,11)
ab <- function(list_a, list_b) {
a_match <- numeric()
b_match <- numeric()
for (i in list_a) {
results <- if(i %in% list_b) {i}
a_match <- c(a_match, results)
}
for (i in list_b) {
results <- if(i %in% list_a) {i}
b_match <- c(b_match, results)
}
combined <- c(a_match,b_match)
unique(combined)
}
ab(a, b)
Комментарии:
1. Большое вам спасибо! Почему для R имеет значение, объявлены ли они внутри или вне функции?
2. @kwsunshine123 Это связано с областью видимости. Все переменные внутри функции должны быть объявлены внутри функции или должны быть переданы в качестве параметра в функцию.
Ответ №2:
мы могли бы просто использовать %in%
функцию для получения элементов, которые находятся в a
и b
=> a %in% b
является логическим вектором, который мы используем для подмножества исходного списка.
a %in% b
#> [1] FALSE FALSE TRUE TRUE TRUE
unique(a[a %in% b])
[[1]]
[1] 3
[[2]]
[1] 4
[[3]]
[1] 5
Имейте в виду, что большинство операторов (функций) в базовом векторизованы, поэтому нет необходимости использовать семейство apply в этом.
unlist(unique(a[a %in% b]))
#> [1] 3 4 5
Комментарии:
1. Спасибо!! Я действительно борюсь с тем, насколько запутан вывод списка (я предполагаю, что вывод, который вы напечатали, представляет собой список). Почему он просто не возвращает аккуратный вектор, соответствующий вводу?
2. @kwsunshine123 поскольку мы задаем подмножество списка, если вы хотите, чтобы он возвращал вектор, оберните его в
unlist
вызов. одна вещь, которая важна в программировании на R, — это использование векторизованного аспекта, поскольку он оптимизирован больше, чем для циклов, и эстетически лучше. Также обратите внимание, что это работает даже для дочерних списков, которые находятся в a и b3. @kwsunshine123 обратите внимание, что если вы хотите, чтобы a и b были вложенными списками, добавьте
recursive=FALSE
к вызову unlist