R、 class()为数据帧列返回不同的结果

R、 class()为数据帧列返回不同的结果,r,R,我很惊讶地发现上面演示的class()行为。有人能给我解释一下上述不一致的原因吗。非常感谢。原因是apply将所有内容转换为字符类,因为它将其转换为矩阵,并且矩阵只能包含一个类,即,如果至少有一列是非数字的,则整个数据集将更改为字符。相反,我们可以使用 > bb = data.frame(x = c( 11:13), y = c(1:3), z = c("a", "a", "b")) > bb x y z 1 11 1 a 2 12 2 a 3 13 3 b > >

我很惊讶地发现上面演示的class()行为。有人能给我解释一下上述不一致的原因吗。非常感谢。

原因是
apply
将所有内容转换为
字符
类,因为它将其转换为
矩阵
,并且
矩阵
只能包含一个类,即,如果至少有一列是非数字的,则整个数据集将更改为
字符
。相反,我们可以使用

> bb = data.frame(x = c( 11:13), y = c(1:3), z = c("a", "a", "b"))
> bb
   x y z
1 11 1 a
2 12 2 a
3 13 3 b
> 
> apply( bb, 2, class)
          x           y           z 
"character" "character" "character" 
>
> apply( bb[,1:2], 2, class)
        x         y 
"integer" "integer" 
>    
> apply( bb[,2:3], 2, class)
          y           z 
"character" "character" 
> 
> class(bb$z)
[1] "factor"
> 
上面返回
列表中的输出。如果我们需要它作为
向量
,请使用
sapply

lapply(bb, class)
#$x
#[1] "integer"

#$y
#[1] "integer"

#$z
#[1] "factor"

您也可以使用
str()
检查数据帧

vapply(bb, class, '')

正如OP在帖子中所显示的,只要是数字列,正确的类就会显示为
apply
,直到一个非数字列被添加到混合中。

请阅读
?apply
:“如果
X
是[…]一个数据帧),
apply
尝试通过
As.matrix
”将其强制到数组中。然后继续阅读
?as.matrix
:“如果只有原子列和任何非-(数字/逻辑/复数)列,则数据帧的方法将返回字符矩阵,[…]否则,将使用通常的强制层次结构(逻辑<整数<双<复数)。”
vapply(bb, class, '')
str(bb)
# 'data.frame': 3 obs. of  3 variables:
#  $ x: int  11 12 13
#  $ y: int  1 2 3
#  $ z: Factor w/ 2 levels "a","b": 1 1 2