这是一个简单的tapply
示例:
z=data.frame(s=as.character(NA), rows=c(1,2,1), cols=c(1,1,2), stringsAsFactors=FALSE)
tapply(z$s, list(z$rows, z$cols), identity)
对于Windows的R(另一个独木舟)v3.3.3(2017-03-06),它带来:
# 1 2
# 1 NA NA
# 2 NA NA
对于Windows的R(You Stupid Darkness)v3.4.0(2017-04-21),它带来:
# 1 2
# 1 NA NA
# 2 NA ""
根据 NEWS.R-3.4.0.:
tapply()
获取新选项default = NA
,允许更改以前的硬编码值。
在这个例子中,似乎它默认为空字符串。
新行为与数字或逻辑版本不一致,其中一个仍然获得所有NAs:
z=data.frame(s=as.numeric(NA), rows=c(1,2,1), cols=c(1,1,2), stringsAsFactors=FALSE)
tapply(z$s, list(z$rows, z$cols), identity)
# 1 2
# 1 NA NA
# 2 NA NA
s=NA
也是如此,这意味着s=as.logical(NA)
。
在更现实的背景下,s
中的字符向量z
有几个值,包括NA。
z=data.frame(s=c('a', NA, 'c'), rows=c(1,2,1), cols=c(1,1,2), stringsAsFactors=FALSE)
m=tapply(z$s, list(z$rows, z$cols), identity)
z;m
# s rows cols
# 1 a 1 1
# 2 <NA> 2 1
# 3 c 1 2
# 1 2
# 1 "a" "c"
# 2 NA ""
一般情况下,对于没有值的组合,我们可能会修复此设置缺失值:
m[!nzchar(m)]=NA; m
# 1 2
# 1 "a" "c"
# 2 NA NA
现在,当没有值时,例如在(2,2)
中,正确获得NA
,就像在旧版本中一样。
但是如果tapply
的输入已经有一些空字符串呢?
z=data.frame(s=c('a', NA, ''), rows=c(1,2,1), cols=c(1,1,2), stringsAsFactors=FALSE)
m=tapply(z$s, list(z$rows, z$cols), identity)
z;m
# s rows cols
# 1 a 1 1
# 2 <NA> 2 1
# 3 1 2
# 1 2
# 1 "a" ""
# 2 NA ""
现在无法区分(1,2)
中的 legal 空字符串和(2,2)
中人工添加的空字符串代替新NA
tapply。所以我们无法应用此修复程序。
新行为真的是正确的吗?
也就是说,如果rows=2
和cols=2
没有字符串,为什么不会将其报告为缺失值(NA
)以及为什么仅对字符数据类型进行报告?
我们能否以这样的方式重写上面的代码以获得跨R版本的一致行为?