最近,我遇到的table
功能行为并非我所期望的:
例如,让我们采取以下向量:
ex_vec <- c("Non", "Non", "Nan", "Oui", "NaN", NA)
如果我检查NA
向量中的值,"NaN"
则不被视为一个(如预期的那样):
is.na(ex_vec) # [1] FALSE FALSE FALSE FALSE FALSE TRUE
但如果我试图获得不同的值频率:
table(ex_vec) #ex_vec #Nan Non Oui # 1 2 1
"NaN"
没有出现在表格中.
但是,如果我"要求" table
显示NA
值,我会得到:
table(ex_vec, useNA="ifany") #ex_vec # Nan NaN Non Oui# 1 1 2 1 1
因此,字符串"NaN"
被视为调用NA
内部的值table
,而在输出中将其视为非NA
值.
我知道(这会更好)我可以通过将我的矢量转换为a来解决我的问题factor
但是,我真的很想知道这里发生了什么.有没有人有想法?
当factor
匹配向量的级别时,它将其exclude
列表转换为与输入向量相同的类型:
exclude <- as.vector(exclude, typeof(x))
因此,如果您的排除列表已经NaN
且您的向量是字符,则会发生以下情况
as.vector(exclude, typeof(letters)) [1] NA "NaN"
噢亲爱的.现在"NaN"
将排除真正的字符串.
要修复,使用exclude=NA
的table
(和factor
如果你作出可能打这个因素).
我喜欢这个文档factor
:
There are some anomalies associated with factors that have ‘NA’ as a level. It is suggested to use them sparingly, e.g., only for tabulation purposes.
令人欣慰的...
我想到的第一个想法是看一下从以下table
开始的定义:
> table function (..., exclude = if (useNA == "no") c(NA, NaN), useNA = c("no", "ifany", "always"), dnn = list.names(...), deparse.level = 1) {
听起来合乎逻辑,默认情况下表排除NA
和NaN
.
在表格代码中挖掘,我们看到,如果x
不是一个因素,它强迫它成为一个因素(这里没有什么新东西,它在文档中说).
else { a <- factor(a, exclude = exclude)
我没有找到任何其他可能影响输入以强制"NaN"
进入NA
价值观的东西.
因此,研究因素,找出我们找到根本原因的原因:
> factor function (x = character(), levels, labels = levels, exclude = NA, ordered = is.ordered(x), nmax = NA) { [...] # Snipped for brievety exclude <- as.vector(exclude, typeof(x)) x <- as.character(x) levels <- levels[is.na(match(levels, exclude))] # defined in the snipped part above, is the sorted unique values of input vector, coerced to char. f <- match(x, levels) [...] f }
在这里,我们得到它,排除参数,甚至是NA
值被强制转换为字符向量.
那么会发生什么:
> ex_vec <- c("Non", "Non", "Nan", "Oui", "NaN", NA) > excludes<-c(NA,NaN) > as.vector(excludes,"character") [1] NA "NaN" > match(ex_vec,as.vector(excludes,"character")) [1] NA NA NA NA 2 1
我们确实匹配字符"NaN"作为排除向量,因为在比较之前被强制转换为字符.