#r #dplyr #tidyr
#r #dplyr #tidyr
Вопрос:
Я пытаюсь объединить несколько столбцов в вектор (в идеале я хотел бы указать, какие столбцы используют какое-либо регулярное выражение или dplyr::contains()
. В любом случае, я НЕ собираюсь объединять столбцы или использовать решение paste
(я хочу иметь возможность использовать %in%
оператор для результирующего вектора. Я хочу, чтобы новый столбец был вектором значений, который можно было бы отменить с помощью unnest_wider
или какой-либо подобной функции. Я уверен, что это возможно, просто пока не могу придумать правильные условия поиска. Это кажется близким, но не работает:
df <- tribble(~A, ~B,
1, 2,
3, 4,
5, 6)
df %>%
mutate(C = I(list(A, B)))
Результат будет выглядеть примерно так
A B C
1 1 2 c(1,2)
2 3 4 c(3,4)
3 5 6 c(5,6)
Ответ №1:
Здесь мы можем либо использовать rowwise
library(dplyr)
df %>%
rowwise %>%
mutate(C = list(c(A, B))) %>%
ungroup
# A tibble: 3 x 3
# A B C
# <dbl> <dbl> <list>
#1 1 2 <dbl [2]>
#2 3 4 <dbl [2]>
#3 5 6 <dbl [2]>
Или с map2
помощью которого по умолчанию возвращается a list
. Здесь мы перебираем соответствующие элементы ‘A’, ‘B’ и объединяем ( c
)
library(dplyr)
library(purrr)
df %>%
mutate(C = map2(A, B, c))
# A tibble: 3 x 3
# A B C
# <dbl> <dbl> <list>
#1 1 2 <dbl [2]>
#2 3 4 <dbl [2]>
#3 5 6 <dbl [2]>
Обновить
Основываясь на комментариях OP, если мы хотим создать list
столбец только со столбцами, имеющими суффикс _id
names(df) <- paste0(names(df), "_id")
df %>%
rowwise %>%
mutate(C = list(c_across(ends_with("_id")))) %>%
ungroup
-вывод
# A tibble: 3 x 3
# A_id B_id C
# <dbl> <dbl> <list>
#1 1 2 <dbl [2]>
#2 3 4 <dbl [2]>
#3 5 6 <dbl [2]>
Если подстрока "_id"
находится в начале, измените значение ends_with
на starts_with
или используйте matches("^_id")
Или с pmap
df %>%
mutate(C = pmap(select(., ends_with("_id")), ~ c(...)))
-вывод
# A tibble: 3 x 3
# A_id B_id C
# <dbl> <dbl> <list>
#1 1 2 <dbl [2]>
#2 3 4 <dbl [2]>
#3 5 6 <dbl [2]>
Или с помощью Map
из base R
df$C <- do.call(Map, c(f = c, df[grep("_id", names(df))]))
Комментарии:
1. Спасибо, этот первый вариант работает, есть идеи о том, как добавить команду grepl для выбора переменных, которые необходимо включить (скажем, только столбцы с префиксом «_id»)? второй вариант работает только для меня, если есть максимум две строки, но может обратиться к другим функциям purr.s
2. @LSmeets Если у вас более одной переменной, вы можете использовать
pmap
вместоmap2
3. @LSmeets вы можете проверить обновленное решение
4. Да, это работает! Спасибо. чтобы добавить функцию фильтра, просто добавьте
%>% rowwise %>% filter(3 %in% C)
к любому из двух вариантов.5. Это очень классные решения! В моем случае мне больше всего понравился этот
c_across
метод, но он медленный с таким гигантским набором данных, как у меня (почти 4 миллиона строк). Для тех, кто читает это, у кого большой набор данных,purrr::pmap
используйте вместо этого решение; это намного быстрее, потому что позволяет избежать необходимости использованияrowwise
.