有人能解释一下为什么我在下面的最后两行代码(identical()
调用)中得到了不同的结果吗?这两个对象看起来是相同的对象,但是当我在apply函数中使用它们时,我遇到了一些麻烦:
df <- data.frame(a = 1:5, b = 6:2, c = rep(7,5))
df_ab <- df[,c(1,2)]
df_AB <- subset(df, select = c(1,2))
identical(df_ab,df_AB)
[1] TRUE
apply(df_ab,2,function(x) identical(1:5,x))
a b
TRUE FALSE
apply(df_AB,2,function(x) identical(1:5,x))
a b
FALSE FALSE
4条答案
按热度按时间pw9qyyiw1#
apply()
函数在对每一列调用该函数之前将其第一个参数强制转换为矩阵。因此,您的 Dataframe 被强制转换为矩阵对象。该转换的结果是as.matrix(df_AB)
具有非空的行名称,而as.matrix(df_ab)
则没有:因此,当
apply()
对df_AB
的列进行子集化时,会得到一个命名向量,它与未命名向量不同。与
subset()
函数相比,它使用i
的值的逻辑向量来选择行。看起来像是用i
的非缺失值子集化data.frame导致row.names
属性中的这种差异:你可以使用
.Internal(inspect(x))
函数来查看data.frames之间的所有细节差异,如果你感兴趣的话,你可以自己查看。正如罗兰在他的评论中指出的那样,您可以使用
.row_names_info()
函数来查看仅行名称中的差异。请注意,当
i
缺失时,.row_names_info()
的结果为负,但如果您使用非缺失i
进行子集,则结果为正。这些值的含义在
?.row_names_info
中解释:cs7cruho2#
如果你想比较
1:5
和列中的值,你不应该使用apply
,因为apply
在应用函数之前会将 Dataframe 转换为矩阵。由于使用[
创建的子集中的行名称(参见@约书亚Ulrich的答案),值1:5
与包含相同值的命名向量不相同。您应该使用
sapply
将identical
函数应用于列。这可以避免将 Dataframe 转换为矩阵:如您所见,在两个数据框中,第一列中的值都等于
1:5
。wwtsj6pe3#
在一个版本(使用
[
)中,列是整数,而在另一个版本(使用subset
)中,列的名称是整数。snz8szmq4#
在提交给
apply
之前,看看这两个对象的结构,只有一个区别:我不认为约书亚当前提供的“子集”作为逻辑索引来解释这一点。为什么row.names = c(NA, -5L))
在使用“[”提取时会产生命名结果还没有解释。我确实同意需要进一步研究的是as.matrix强制: