【问题标题】:Order and subset a multi-column dataframe in R?在 R 中对多列数据框进行排序和子集化?
【发布时间】: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 列数据框只包含一个向量,但它仍然包含在数据框中?)
  2. 是否可以在 1 步中对多列数据帧进行排序和子集化?

【问题讨论】:

  • 当只选择一列时,R 中的 data.frames 会自动简化为向量:stackoverflow.com/questions/21025609/…(您可以使用drop=FALSE 防止这种情况发生)。子集和排序是两种不同的操作。你应该分两个逻辑步骤(但可能是一行代码)。

标签: r dataframe subset


【解决方案1】:

仅选择一列时,R 中的 data.frame 会自动简化为向量。这是一种常见且有用的简化,在this question 中有更好的描述。当然,您可以使用drop=FALSE 来防止这种情况发生。

子集和排序是两种不同的操作。您应该分两个逻辑步骤(但可能是一行代码)来完成它们。这条线没有多大意义

df[order(df$x) & df$x < 5,]

R 中的子集可以使用行索引向量(order() 返回)或布尔值(&lt; 比较返回)来完成。混合它们(仅使用&amp;)并不能清楚地说明 R 应该如何执行子集。但是您可以使用subset() 将其分为两个步骤

subset(df[order(df$x),], x < 5)

这首先进行排序,然后是子集。请注意,该条件不再专门引用 df 的值,它将从重新排序的 data.frame 中过滤数据。

这样的操作是许多人偏爱dplyr 库进行数据操作的原因之一。例如,这可以通过

library(dplyr)
dd <- data.frame(x = sample(1:50))
dd %>% filter(x<5) %>% arrange(x)

【讨论】:

    猜你喜欢
    • 2016-09-28
    • 2021-12-04
    • 1970-01-01
    • 2019-09-26
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    • 2022-12-18
    • 1970-01-01
    相关资源
    最近更新 更多