如何避免dcast()输出中的NA列?

时间:2015-10-04 08:21:47

标签: r na reshape2

如何避免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 个答案:

答案 0 :(得分:1)

以下是我能够解决这个问题的方法:

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

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

x$None <- NULL

我们的想法是将所有的NA替换为“无”,以便dcast创建一个名为“无”的列。而不是&#39; NA&#39;。然后,如果您不需要,可以在下一步中删除该列。

答案 1 :(得分:0)

我发现的一个解决方案,我并不满意,是基于评论中建议的降低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

答案 2 :(得分:0)

您可以重命名输出的NA列,然后将其设为NULL。 (这对我有用)。

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

答案 3 :(得分:-2)

library(dplyr)
library(tidyr)
iris %>%
  filter(!is.na(Species2)) %>%
  group_by(Species, Species2) %>%
  summarize(freq = n()) %>%
  spread(Species2, freq)