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

问题描述:

如何避免NAdcast()reshape2封装输出?如何避免dcast()输出中的NA列?

在该虚设示例的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列? (此功能有许多被严厉地记录,并且我不能完全把握非常模糊的选项...)

+0

你可以做'dcast(na.omit(光圈),种类〜Species2,value.var =“Sepal.Width”)',但这不是很通用的解决方案,如果你有兴趣在其他一些列了。 –

+0

@DavidArenburg确实。我意识到'na.omit(虹膜)式的解决方案,但我正在寻找不同的方法。我并没有包括在这个问题以避免使它太混乱了这个要求...... – landroni

+1

如果我猜的话,我会说这是预期的行为,所以你需要有意识地删除丢失的数据(而不是做不小心)。我会首先选择数据来解决它,所以'iris [!is.na(iris $ Species2),]'。 – Heroka

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

所有说的和做的,我宁愿一个'dcast()'为基础的解决方案,如果可能的话。 – landroni

+0

为什么人们低估这个答案? –

+2

@MikeWise我不知道,但我怀疑,因为它提出了一个替代性的,而不是试图将问题的约束范围内解决这个问题(即'dcast()'函数)。我不同意虽然这downvotes没有任何* *解释是围绕SE最消极和适得其反,社会的角度来看,hehaviors之一...... – landroni

一个解决方案,我已经找到了,这我不肯定不高兴,基于在评论中建议的降低NA值的方法。它利用从plyrdcast()subset参数与.()一起:

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 

你可以重命名的的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 

这里是我如何能够绕过它:

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

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

x$None <- NULL 

的想法是,你与“无”替换所有来港,让dcast创建一个名为“无”,而列比'不适用'。然后,如果不需要,可以在下一步中删除该列。

+0

您可以将代码格式化为代码,使其更易于阅读吗? (缩进4个空格,或者使用'{}'按钮。)另外,请添加一个解释,以便其他人可以更好地理解您的解决方案。 – Robert