R - tidyr - spread() - 将NA作为列名处理

时间:2015-10-17 20:13:16

标签: r na piping tidyr spread

我使用tidyr::spread()将多个分类变量传播到布尔列。由于数据包含NA,spread会创建一个没有名称的新列。

我正在寻找的是一种使用

摆脱NA的方法

a)管道解决方案(我已尝试select_()'['(),但不知道如何引用NA列的名称或索引)或

b)自定义功能,哪个更好

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 个答案:

答案 0 :(得分:2)

我们可以将selectbackquotes一起用于“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列,因为其他列中的观察结果与之相关。我们可以使用filteris.na来删除'flower'列中包含'NA'的行,但之后我们会丢失一行,即。第3行。

答案 1 :(得分:0)

根据@ 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

}