R - tidyr - spread() - имеет дело с NA в качестве имени столбца

Я распространяю несколько категориальных переменных на логические столбцы, используя tidyr::spread(), Поскольку данные содержат НС, spread создает новый столбец без имени.

То, что я ищу, это способ избавиться от АН, используя

а) решение трубопровода (я пробовал select_() а также '['(), но не знаю, как ссылаться на имя или индекс столбца NA) или

б) пользовательская функция, которая была бы еще лучше

c) способ просто не генерировать столбцы NA, совместимые с Hadleyverse, если это возможно.

Ниже мое текущее (и очень неуклюже повторяющееся) решение.

library(tidyr)
library(dplyr)

test <- data.frame(id = 1:4, name = c("anna", "bert", "charles", "daniel"),
                   flower = as.factor(c("rose", "rose", NA, "petunia")),
                   music = as.factor(c("pop","classical", "rock", NA)),
                   degree = as.factor(c(NA, "PhD", "MSc", "MSc")))

test <- test %>% 
  mutate(truval = TRUE) %>% 
  spread(key = flower, value = truval, fill = FALSE)
test[ncol(test)] <- NULL

test <- test %>% 
  mutate(truval = TRUE) %>% 
  spread(key = music, value = truval, fill = FALSE)
test[ncol(test)] <- NULL

test <- test %>% 
  mutate(truval = TRUE) %>% 
  spread(key = degree, value = truval, fill = FALSE)
test[ncol(test)] <- NULL

test

2 ответа

Решение

Мы можем использовать select с backquotes для столбца "NA".

 test %>% 
    mutate(truval= TRUE) %>% 
    spread(flower, truval, fill=FALSE) %>% 
    select(-`NA`)
 #  id    name     music degree petunia  rose
 #1  1    anna       pop   <NA>   FALSE  TRUE
 #2  2    bert classical    PhD   FALSE  TRUE
 #3  3 charles      rock    MSc   FALSE FALSE
 #4  4  daniel      <NA>    MSc    TRUE FALSE

Я предполагаю, что трудно не генерировать столбец NA, поскольку наблюдения в других столбцах привязаны к нему. Мы могли бы использовать filter с is.na удалить строку, которая имеет "NA" в столбце "цветок", но тогда мы потеряем одну строку, т.е. 3-й ряд.

Согласно ответу @akrun, вы можете использовать ссылку на NA с обратными кавычками. И вот функция позаботиться об этом:

Spread_bool <- function(df, varname) {
# spread a categorical variable to Boolean columns, remove NA column
# Input:
#  df: a data frame containing the variable to be spread
#  varname: the "quoted" name of the variable to be spread
#
# Return:
#  df: a data frame with the variable spread to columns

  df <- df %>% 
    mutate(truval = TRUE) %>% 
    spread_(varname, "truval", fill = FALSE) %>% 
    select(-`NA`)

  df

}
Другие вопросы по тегам