当我使用以下data.frame
时JobScheduler
然后
dataSet <- structure(list(J1 = "foo", J2 = structure(0.1, .Dim = c(1L, 1L
))), .Names = c("J1", "J2"), row.names = 1L, class = "data.frame")
返回
print(colnames(dataSet))
正如所料。
然而,
[1] "J1" "J2"
返回
r <- is.na(dataSet)
print(colnames(r))
为什么会这样?我以这种奇怪的方式创建data.frame,因为我在将一个真实的data.frame压缩到一个最小的工作示例之后使用dput()创建了代码。我正在使用的函数依赖于假设is.na保留了colnames,这似乎适用于大多数data.frames但不适用于此。
答案 0 :(得分:3)
请记住,您的第二列是未命名的矩阵。
sapply(dataSet, class)
# J1 J2
# "character" "matrix"
现在让我们看一下is.na
中发生的事情。 is.na
的数据框方法的前几行是
head(is.na.data.frame, 5)
#
# 1 function (x)
# 2 {
# 3 y <- if (length(x)) {
# 4 do.call("cbind", lapply(x, "is.na"))
# 5 }
is.na.data.frame
是用R编写的,因此我们可以通过将数据集插入步骤来轻松调试问题。
lapply(dataSet, is.na)
# $J1
# [1] FALSE
#
# $J2
# [,1]
# [1,] FALSE
do.call(cbind, lapply(dataSet, is.na))
# J1
# [1,] FALSE FALSE
所以我们知道它发生在cbind.
现在,如果我们转到help(cbind)
,我们会发现
对于
cbind
(rbind
),列(行)名称取自参数的colnames
(rownames
),如果这些是类似矩阵的话。
这里讨论的论点是第二列中的矩阵。名称取自该矩阵,而不是数据框列表名称。由于矩阵上没有任何名称,因此生成的第二列名称为空白。
这个特定问题的快速解决方案是简单地连接第二列。
is.na(lapply(dataSet, c))
# J1 J2
# FALSE FALSE