【问题标题】:Is there a base R function to dynamically order data.frame columns similar to dplyr everything()?是否有一个基本的 R 函数来动态排序类似于 dplyr Everything() 的 data.frame 列?
【发布时间】:2019-11-25 04:31:53
【问题描述】:

假设您有一个 data.frame,并且您希望使用基本 R 动态地重新排序列。输入数据将始终看起来像这样。它将始终包含idmonthyear 变量,以及可变数量的数据变量(表示为v1v2v3 等)

df1 <- data.frame(
  id = 1:5,
  v1 = LETTERS[1:5],
  v2 = rep(2,5),
  v3 = rep(10,5),
  month = c("jan", "jan", "mar", "oct", "dec"),
  year = c(1999, 2001, 1984, 1979, 2019),
  stringsAsFactors = F)

我想重新排序列,使idmonthyear 始终是前三列,然后将数据变量从第 4 列开始放置。

df2 <- data.frame(
  id = 1:5,
  month = c("jan", "jan", "mar", "oct", "dec"),
  year = c(1999, 2001, 1984, 1979, 2019),
  v1 = LETTERS[1:5],
  v2 = rep(2,5),
  v3 = rep(10,5),
  stringsAsFactors = F)

我知道这可以通过 dplyr::selectdplyr::everything 来完成。

library(dplyr)
df2 <- df1 %>% select(id, month, year, everything())

但我想使用 base R 实现相同的输出。

我想到的最好的是,

keep1 <- c("id", "month", "year")
keep2 <- names(df1)[!names(df1) %in% keep1]
keep3 <- c(keep1, keep2)
df2 <- df1[, keep3]

可能有更优雅的解决方案吗?比如,R 中是否有类似于dplyr::everything 的函数?

【问题讨论】:

    标签: r


    【解决方案1】:

    你可以使用setdiff:

    df1[, c(keep1, setdiff(names(df1), keep1))]
    

    【讨论】:

      【解决方案2】:
      df1[order(match(names(df1), keep1, nomatch = NCOL(df1) + 1))]
      #  id month year v1 v2 v3
      #1  1   jan 1999  A  2 10
      #2  2   jan 2001  B  2 10
      #3  3   mar 1984  C  2 10
      #4  4   oct 1979  D  2 10
      #5  5   dec 2019  E  2 10
      

      【讨论】:

      • 很好,我实际上更喜欢这个解决方案,因为它不会重复 keep1,因此允许直接指定名称,而无需先将它们存储在变量中。
      【解决方案3】:

      另一种选择

      df1[, unique(c(which(names(df1) %in% keep1), seq_along(df1)))]
      

      df1[, unique(c("id", "month", "year", names(df1)))]
      

      【讨论】:

      • 第二种解决方案非常简洁!
      猜你喜欢
      • 2020-06-14
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 2012-04-08
      • 2015-02-23
      • 1970-01-01
      • 2021-10-22
      • 1970-01-01
      相关资源
      最近更新 更多