【发布时间】:2017-07-29 08:00:21
【问题描述】:
我想按某个列和子集排序一个多列数据框,但使用的命令不起作用
print(df[order(df$x) & df$x < 5,])
这不对结果进行排序。
为了调试它,我生成了一个包含 1 列的测试数据框,但这种“简化”产生了意想不到的效果
df <- data.frame(x = sample(1:50))
print(df[order(df$x) & df$x < 5,])
这不会对结果进行排序,所以我觉得我已经重现了问题,但使用了更简单的数据。
将过程分解为先排序然后子集导致我发现在这种情况下排序不会生成数据框对象
df <- data.frame(x = sample(1:50))
ndf <- df[order(df$x),]
print(class(ndf))
生产
[1] "integer"
尝试使用数据框语法对生成的“整数”ndf 对象进行子集化,例如
print(ndf[ndf$x < 5, ])
显然会产生错误:
Error in ndf$x : $ operator is invalid for atomic vectors.
进一步简化,我发现单独设置子集(不应用 order 函数)不会生成数据框对象
ndf <- df[df$x < 5,]
class(ndf)
[1] "integer"
事实证明,分离排序和子集的多列数据框确实按预期工作
df <- data.frame(x = sample(1:50), y = rnorm(50))
ndf <- df[order(df$x),]
print(ndf[ndf$x < 5, ])
这解决了我原来的问题,但又引出了两个问题:
- 为什么返回的对象类型,如上所述,基于 1 列数据帧测试用例,而不是数据帧? (我很欣赏 1 列数据框只包含一个向量,但它仍然包含在数据框中?)
- 是否可以在 1 步中对多列数据帧进行排序和子集化?
【问题讨论】:
-
当只选择一列时,R 中的 data.frames 会自动简化为向量:stackoverflow.com/questions/21025609/…(您可以使用
drop=FALSE防止这种情况发生)。子集和排序是两种不同的操作。你应该分两个逻辑步骤(但可能是一行代码)。