一致地将矩阵子集转换为向量并避免使用列名?

5
我想知道是否有R语法可以从矩阵中提取一列并始终在返回的向量上没有名称属性(我希望依赖这种行为)。
我的问题是以下不一致性:
- 当矩阵具有多行且我执行myMatrix [,1]时,我将获得myMatrix的第一列,其没有名称属性。这就是我想要的。 - 当矩阵恰好有一个行时,我执行myMatrix [,1],我将获得myMatrix的第一列,但它具有第一个colname作为其名称。
我希望能够执行myMatrix [,1]并始终获得无名称的内容。
下面是一个示例:
# make a matrix with more than one row,
x <- matrix(1:2, nrow=2)
colnames(x) <- 'foo'
#      foo
# [1,]   1
# [2,]   2

# extract first column. Note no 'foo' name is attached.
x[, 1]
# [1] 1 2

# now suppose x has just one row (and is a matrix)
x <- x[1, , drop=F]
# extract first column
x[, 1]
# foo    # <-- we keep the name!!
#   1

现在,[ (?'[') 的文档提到了这种行为,所以这不是一个错误或者其他什么(尽管,为什么?!为什么这个不一致性?!):
通过矩阵索引获得的向量将没有名称,除非‘x’是一维的,此时行名称(如果有)将被索引以为结果提供名称。 我的问题是,是否有一种方法可以执行 x[, 1],使结果总是未命名,其中x是一个矩阵?
我的唯一希望是使用 unname(x[, 1]),还是有类似于[drop参数的东西?还是有一个我可以设置的选项来表示“总是未命名”?我可以使用的一些技巧(某种方式覆盖[的行为,当提取的结果是一个向量时?)

由于您想要一个单列矩阵,我会使用as.vector(x[,1])来实现。 - agstudy
"dimnames<-"(x,NULL)[,1] - James
@agstudy:我不想要一个列矩阵,我只想让结果无论是什么都没有名称。无论如何,as.vector(x[,1])会产生一个向量,它不是一个一列矩阵,并且仍然带有名称。 - mathematical.coffee
1个回答

1

以下是代码为何有效的更新(据我所知)

使用 [ 进行子集处理时,使用包含于 R 源文件 subset.c 中的函数,在 ~/src/main 中。当使用矩阵索引对矩阵进行子集处理时,将调用函数 VectorSubset。当使用多个索引(例如,每个索引分别用于行和列,如 x[,1])时,则会调用 MatrixSubset

函数 VectorSubset 仅为被子集化的 1 维数组分配名称。由于矩阵是一个 2 维数组,因此在使用矩阵索引时不会为结果分配名称。但是,函数 MatrixSubset 在某些情况下会尝试传递 dimnames。


因此,您在帮助页面引用的矩阵索引似乎是关键:
x <- matrix(1)
colnames(x) <- "foo"
x[, 1]  ## 'Normal' indexing
# foo 
#   1 
x[matrix(c(1, 1), ncol = 2)]  ## Matrix indexing
# [1] 1

而且,使用更宽的1行矩阵:
xx <- matrix(1:10, nrow = 1)
colnames(xx) <- sprintf('foo%i', seq_len(ncol(xx)))
xx[, 6]  ## 'Normal' indexing
# foo6 
#    6 
xx[matrix(c(1, 6), ncol = 2)]  ## Matrix indexing
# [1] 6

使用一个行和列都大于1的矩阵:
yy <- matrix(1:10, nrow = 2, dimnames = list(NULL,
  sprintf('foo%i', 1:5)))

yy[cbind(seq_len(nrow(yy)), 3)]  ## Matrix indexing
# [1] 5 6

@mathematical.coffee,经过进一步调查,我相当有信心地认为矩阵索引将始终返回矩阵的未命名子集。 - BenBarnes
啊,这就有意义了,矩阵索引。不幸的是,它仍然不如 unname(x[, 1]) 简洁!感谢您挖掘出来的信息! - mathematical.coffee
@mathematical.coffee,是的,你建议使用unname应该没问题!我发现定期查看R源代码很有趣也很令人感到谦卑,所以感谢你提供的借口。 - BenBarnes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接