apply()
函数在调用每一列的函数之前,将第一个参数强制转换为矩阵。因此你的数据框被强制转换为矩阵对象。该转换的一个结果是 as.matrix(df_AB)
具有非空行名称,而 as.matrix(df_ab)
则没有:
> str(as.matrix(df_ab))
int [1:5, 1:2] 1 2 3 4 5 6 5 4 3 2
- attr(*, "dimnames")=List of 2
..$ : NULL
..$ : chr [1:2] "a" "b"
> str(as.matrix(df_AB))
int [1:5, 1:2] 1 2 3 4 5 6 5 4 3 2
- attr(*, "dimnames")=List of 2
..$ : chr [1:5] "1" "2" "3" "4" ...
..$ : chr [1:2] "a" "b"
当你使用apply()
函数对df_AB
的列进行子集操作时,你会得到一个命名向量,它与未命名向量不完全相同。
apply(df_AB, 2, str)
Named int [1:5] 1 2 3 4 5
- attr(*, "names")= chr [1:5] "1" "2" "3" "4" ...
Named int [1:5] 6 5 4 3 2
- attr(*, "names")= chr [1:5] "1" "2" "3" "4" ...
NULL
与此相比,subset()
函数使用逻辑向量来选择行的值,而看起来用非缺失值的i
对数据框进行子集操作会导致row.names
属性的差异:
> str(as.matrix(df[1:5, 1:2]))
int [1:5, 1:2] 1 2 3 4 5 6 5 4 3 2
- attr(*, "dimnames")=List of 2
..$ : chr [1:5] "1" "2" "3" "4" ...
..$ : chr [1:2] "a" "b"
> str(as.matrix(df[, 1:2]))
int [1:5, 1:2] 1 2 3 4 5 6 5 4 3 2
- attr(*, "dimnames")=List of 2
..$ : NULL
..$ : chr [1:2] "a" "b"
您可以使用.Internal(inspect(x))
函数查看数据框之间的所有差异细节。如果您感兴趣,可以自行查看。
正如Roland在评论中指出的那样,您可以使用.row_names_info()
函数仅查看行名称的差异。
请注意,当i
缺失时,.row_names_info()
的结果是负数,但如果您使用非缺失的i
进行子集划分,则结果为正数。
> .row_names_info(df_ab, type=1)
[1] -5
> .row_names_info(df_AB, type=1)
[1] 5
这些值的含义在?.row_names_info
中解释:
type: integer. Currently ‘type = 0’ returns the internal
‘"row.names"’ attribute (possibly ‘NULL’), ‘type = 2’ the
number of rows implied by the attribute, and ‘type = 1’ the
latter with a negative sign for ‘automatic’ row names.
[
创建了“自动”行名(请参见.row_names_info(df_ab, type=1)
),而subset
则创建了显式行名(请参见.row_names_info(df_AB, type=1)
)。as.matrix
只是传播了这一点(矩阵不必具有行名)。 - Rolandidentical(df_ab, df_AB)
应该返回 false? - Señor Oidentical(df_AB, df_ab, attrib.as.set=FALSE)
返回 FALSE。 - Josh O'Brienrow.names
的值不同,但不应该由as.matrix
自动命名。这不是subset
做的命名。 - IRTFMas.matrix.data.frame
中两个对象分歧处(即df_ab
在其行名称上获取NULL的位置)更精确的信息。 - Josh O'Brien