Можно ли объединить столбцы фрейма данных на основе индекса столбца, хранящегося в виде вектора, возможно, используя функцию stringr (например, str_c ()) или вставить? И затем, как я могу это сделать, чтобы создать новую переменную с помощью dplyr mutate ()?
Я хотел бы сделать это для задачи агрегации электронной почты, которая будет означать чтение листов Excel, содержащих столбцы с различными именами (например, только один столбец имени, а иногда и имя и фамилия), используя пакет readxl.
Например: Скажем, я хотел объединить все имена столбцов, содержащие слово «цвет», во фрейме данных starwars, установленном с пакетом tidyverse R.
library(tidyverse)
colnames(starwars)
[1] "name" "height" "mass" "hair_color" "skin_color" "eye_color" "birth_year" "gender" "homeworld" "species" "films"
[12] "vehicles" "starships"
Я мог бы зафиксировать индекс этих столбцов с помощью:
color_vec_num <- which(grepl("COLOR", toupper(colnames(starwars))))
print(color_vec_num)
[1] 4 5 6
Какие названия столбцов?
colnames(starwars)[color_vec_num]
[1] "hair_color" "skin_color" "eye_color"
Я могу достаточно легко связать имена этих столбцов по имени. Взглянем на первые 4 ряда звездных войн:
str_c(starwars$hair_color, starwars$skin_color, starwars$eye_color)[1:4]
[1] "blondfairblue" NA NA "nonewhiteyellow"
Однако мои попытки использовать индекс столбца не увенчались успехом.
Редактировать за обнаружение Акруном опечатки Заимствование этого ТАК использование двойных скобок для создания (изменения) новой переменной работает, но это идентифицирует столбцы по отдельности и явно, а не использует числовой вектор для идентификации каждого индекса столбца.
starwars %>% mutate(newcolor = paste(.[[4]],.[[5]], .[[6]])) %>% select(name, newcolor)
# A tibble: 87 x 2
name newcolor
<chr> <chr>
1 Luke Skywalker blond fair blue
2 C-3PO NA gold yellow
3 R2-D2 NA white, blue red
Эта попытка, напоминающая предыдущий ответ SO на другой вопрос, явно не выглядит правильной.
paste(starwars %>% select(color_vec_num), collapse = " ", stringsAsFactors = FALSE)
[1] "c(\"blond\", NA, NA, \"none\", \"brown\", \"brown, grey\", \"brown\", NA, \"black\", \"auburn, white\", \"blond\", \"auburn, grey\", \"brown\", \"brown\", NA, NA,
Мы можем подмножество столбцов с индексом столбца (.[color_vec_num]
) и reduce
в один столбец / вектор в mutate
путем конкатенации (str_c
)
library(tidyverse)
out <- starwars %>%
mutate(newcolor = reduce(.[color_vec_num], str_c))
out %>%
pull(newcolor) %>%
head(4)
#[1] "blondfairblue" NA NA "nonewhiteyellow"
По поводу ошибки в OP's paste
paste(.[[4]],.[[5]], [[6]]
в последнем отсутствует .
, т.е. он должен быть
starwars %>%
mutate(newcolor = paste(.[[4]],.[[5]], .[[6]]))
При этом существует явное преимущество использования str_c
по сравнению с paste
или unite
(от tidyr
) в отношении пропущенных значений. С str_c
любое отсутствующее значение в столбце возвращает NA
для всей строки, в то время как paste
или unite
преобразует NA
в символ и возвращает что-то вроде
"NA gold yellow"
для второго элемента, пока это NA
для str_c