Как избежать столбцов NA в выводе dcast()?

Как я могу избежать NA столбцы в dcast() выход из reshape2 пакет?

В этом фиктивном примере dcast() выход будет включать NA колонка:

require(reshape2)
data(iris)
iris[ , "Species2"] <- iris[ , "Species"]
iris[ 2:7, "Species2"] <- NA
(x <- dcast(iris, Species ~ Species2, value.var = "Sepal.Width", 
            fun.aggregate = length))
##     Species setosa versicolor virginica NA
##1     setosa     44          0         0  6
##2 versicolor      0         50         0  0
##3  virginica      0          0        50  0

Для несколько похожего варианта использования, table() есть опция, позволяющая избежать этого:

table(iris[ , c(5,6)], useNA = "ifany")  ##same output as from dcast()
##            Species2
##Species      setosa versicolor virginica <NA>
##  setosa         44          0         0    6
##  versicolor      0         50         0    0
##  virginica       0          0        50    0
table(iris[ , c(5,6)], useNA = "no")  ##avoid NA columns
##            Species2
##Species      setosa versicolor virginica
##  setosa         44          0         0
##  versicolor      0         50         0
##  virginica       0          0        50

Есть ли dcast() есть аналогичная опция, которая удаляет NA столбцы в выводе? Как я могу избежать NA столбцы? (У этой функции есть несколько довольно загадочных опций, которые строго задокументированы и которые я не могу понять...)

4 ответа

Вот как я смог обойти это:

iris[is.na(iris)] <- 'None'

x <- dcast(iris, Species ~ Species2, value.var="Sepal.Width", fun.aggregate = length)

x$None <- NULL

Идея состоит в том, что вы заменяете все NA на "None", так что dcast создает столбец с именем "None", а не "NA". Затем вы можете просто удалить этот столбец на следующем шаге, если он вам не нужен.

Вы можете переименовать столбец NA вывода и затем сделать его пустым. (Это работает для меня).

require(reshape2)
data(iris)
iris[ , "Species2"] <- iris[ , "Species"]
iris[ 2:7, "Species2"] <- NA

(x <- dcast(iris, Species ~ Species2, value.var = "Sepal.Width", 
            fun.aggregate = length)) 

setnames(x , c("setosa", "versicolor", "virginica", "newname"))

x$newname <- NULL

Одно решение, которое я нашел, и которое не является положительно недовольным, основано на подходе сбрасывания значений NA, предложенном в комментариях. Это использует subset аргумент в dcast() вместе с .() от plyr:

require(plyr)
(x <- dcast(iris, Species ~ Species2, value.var = "Sepal.Width",
            fun.aggregate = length, subset = .(!is.na(Species2))))
##     Species setosa versicolor virginica
##1     setosa     44          0         0
##2 versicolor      0         50         0
##3  virginica      0          0        50

Для моей конкретной цели (в рамках пользовательской функции) лучше работает следующее:

(x <- dcast(iris, Species ~ Species2, value.var = "Sepal.Width", 
            fun.aggregate = length, subset = .(!is.na(get("Species2")))))
##     Species setosa versicolor virginica
##1     setosa     44          0         0
##2 versicolor      0         50         0
##3  virginica      0          0        50
library(dplyr)
library(tidyr)
iris %>%
  filter(!is.na(Species2)) %>%
  group_by(Species, Species2) %>%
  summarize(freq = n()) %>%
  spread(Species2, freq)
Другие вопросы по тегам