考虑以下模拟代码段:
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的错误吗?
您描述的行为是设计使然,并记录在?subset
帮助页面上。
从帮助页面:
对于数据帧,subset参数适用于行。请注意,子集将在数据框中求值,因此可以将列(按名称)称为表达式中的变量(请参见示例)。
在R中,data.frame和矩阵是非常不同类型的对象。如果这引起了问题,则可能是因为您的数据使用了错误的数据结构。仅当您对矩阵算术进行运算时,才真正需要矩阵。如果您将列视为行观察的不同属性,那么首先应该将数据存储在data.frame中。您可以将所有值存储在一个简单的向量中,其中每三个值代表一个观测值,但这对于数据的数据结构而言是一个较差的选择。我不确定您是否试图通过选择矩阵来提高效率,但这似乎只是错误的选择。
data.frame存储为命名列表,而矩阵存储为尺寸向量。列表可以用作环境,从而可以轻松地在该上下文中评估变量名称。两者之间的最大区别是data.frame可以容纳不同类的列(数字,字符,日期),而矩阵只能容纳恰好一个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()
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句