【问题标题】:matrix subseting by column's name using `subset` function使用 `subset` 函数按列名进行矩阵子集化
【发布时间】:2017-01-13 22:59:02
【问题描述】:

考虑以下模拟sn-p:

k <- 1:5
x <- seq(0,10,length.out =  100)
dsts <- lapply(1:length(k), function(i) cbind(x=x, distri=dchisq(x,k[i]),i) )
dsts <- do.call(rbind,dsts)

为什么这段代码会报错(dsts是矩阵):

subset(dsts,i==1)
#Error in subset.matrix(dsts, i == 1) : object 'i' not found

即使是这个:

colnames(dsts)[3] <- 'iii'
subset(dsts,iii==1)

但不是这个(矩阵强制为数据框):

subset(as.data.frame(dsts),i==1)

这个可以在 x 已经定义的地方工作:

subset(dsts,x> 500)

错误发生在subset.matrix()这一行:

else if (!is.logical(subset)) 

这是一个应该报告给 R Core 的错误吗?

【问题讨论】:

  • 列名评估仅适用于 data.frames,不适用于矩阵。这就是子集的设计方式。它在文档中有所描述。这不是错误。
  • 您会很高兴听到不建议将此功能用于非交互式使用:This is a convenience function intended for use interactively. For programming it is better to use the standard subsetting functions like [, and in particular the non-standard evaluation of argument subset can have unanticipated consequences.
  • @aichao 不清楚您的示例应该如何工作。 OP 已经有一个包含定义变量的列,应该用于子集。
  • 这里的要点是,除非您需要矩阵运算,否则最好将数据存储在 data.frame 中。这就是R路。您可以使用cbind.data.frame 更明确。
  • @MrFlick 我认为您应该将您的 cmets 表达为一个完整的答案。

标签: r debugging matrix dataframe subset


【解决方案1】:

您描述的行为是设计使然,并记录在?subset 帮助页面上。

从帮助页面:

对于数据框,子集参数适用于行。请注意,subset 将在数据框中进行评估,因此可以(按名称)将列称为表达式中的变量(参见示例)。

在 R 中,data.frames 和矩阵是非常不同类型的对象。如果这导致了问题,那么您可能为数据使用了错误的数据结构。仅当您使用矩阵算术时,才真正需要矩阵。如果您将列视为行观察的不同属性,那么您应该首先将数据存储在 data.frame 中。您可以将所有值存储在一个简单的向量中,其中每三个值代表一个观察值,但这对于您的数据来说也是一个糟糕的数据结构选择。我不确定您是否想通过选择矩阵来提高效率,但这似乎是错误的选择。

data.frame 存储为命名列表,而矩阵存储为维度向量。列表可以用作一个环境,可以很容易地在该上下文中评估变量名。两者最大的区别在于 data.frames 可以保存不同类(数字、字符、日期)的列,而矩阵只能保存一种 data.type 的值。您不能总是在不丢失信息的情况下轻松地在两者之间进行转换。

$ 之类的想法也仅适用于 data.frames。

dd <- data.frame(x=1:10)
dd$x
mm <- matrix(1:10, ncol=1, dimnames=list(NULL, "x"))    
mm$x # Error

如果要对矩阵进行子集化,最好使用标准的[ 子集而不是子集函数。

dsts[ dsts[,"i"]==1, ]

这种行为长期以来一直是 R 的一部分。对此行为的任何更改都可能会对依赖于在特定上下文中评估的变量的现有代码进行重大更改。我认为问题出在谁告诉你首先使用矩阵。而不是cbind(),你应该使用data.frame()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    • 2018-08-07
    • 2014-02-02
    • 1970-01-01
    相关资源
    最近更新 更多