【问题标题】:R function to order data.frames held in a list objectR函数对列表对象中保存的data.frames进行排序
【发布时间】:2020-07-04 03:27:30
【问题描述】:

我正在尝试找到一个优雅的函数来对列表对象中保存的 data.frames 进行排序。我已经知道 lapply(df, function(x) x[with(x, order(var)), ]) 工作正常,但这似乎太复杂了。我正在尝试使用“[”函数,如果我手动输入行号,它可以正常工作。但是很明显,我想使用 order 函数生成的行号。

df <- list(
    data.frame(name = c("John", "Paul", "George", "Ringo"),   height = c(60, 58, 65, 55)),
    data.frame(name = c("Frank", "Tony", "Arthur", "Edward"), height = c(55, 65, 60, 50))
)

lapply(df, "[", c("height", "name"))

lapply(df, "[", c(3:1), )

order <- lapply(df, with, order(name))

order

lapply(df, with, order(name), "[")

lapply(df, with, "[", order(name), )

lapply(df, "[", with, order(name), )

Map("[", order , , df)

【问题讨论】:

  • 是的,这是正确的。此外,通常如何在列表对象上使用 lapply 或 Map 函数时正确地为“[”函数提供参数。

标签: r list dataframe sorting


【解决方案1】:

其他软件包会简化这一点。如果您想使用 base,您可以使用 Map() 扩展您尝试的内容:

order <- lapply(df, with, order(name))
Map("[", df, order, TRUE)
#pseudo translation: df[order, TRUE]
## where TRUE will repeat and select all columns of df

使用 base 的最简单方法是继续处理您建议的过于复杂的内容。您可以使用预制函数进行简化:

lapply(df, function(x) x[order(x[["name"]]), ])

#or
fx_reorder = function (x, col){
  x[order(x[[col]]), ]
}

lapply(df, fx_reorder, "name")

## or to accept multiple columns
fx_reorder2 = function(x, cols) {
  if (missing(cols)) cols = names(x)
  x[do.call("order", x[cols]), ]
}

lapply(df, fx_reorder2)
lapply(df, fx_reorder2, "name")
lapply(df, fx_reorder2, 1:2)

【讨论】:

    【解决方案2】:

    您熟悉dplyr 包吗?你可以把arrange函数放在lapply里面。

    lapply(df, arrange, -height)
    

    如果您不熟悉dplyr,我会调查一下。听起来您的问题可能可以通过 bind_rowsgroup_by 解决。

    【讨论】:

      【解决方案3】:

      如果您使用library(data.table) 而不是data.frame,那么解决方案非常优雅。

      我们可以使用lapply(df, setDT) 将您的对象转换为data.table。请注意,如果您首先将对象创建为 data.table,则不需要此步骤,这将是一个更典型的工作流程。

      然后可以使用来完成排序

      lapply(df, setkey, 'name')
      
      # [[1]]
      #      name height
      # 1: George     65
      # 2:   John     60
      # 3:   Paul     58
      # 4:  Ringo     55
      # 
      # [[2]]
      #      name height
      # 1: Arthur     60
      # 2: Edward     50
      # 3:  Frank     55
      # 4:   Tony     65
      

      【讨论】:

        【解决方案4】:

        我们可以使用arrangemap

        library(dplyr)
        library(purrr)
        map(df,  ~ .x %>% 
                      arrange(name))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-22
          • 1970-01-01
          • 2016-11-03
          相关资源
          最近更新 更多