在r中对嵌套列表进行排序

时间:2014-12-04 20:58:23

标签: r list sorting

我有几个列表,每个列表包含N个对象(如下面的unsorted$b)和一个包含N行(unsorted$a以下)的数据框。所有这些都在一个列表中(unsorted)。我希望对数据框进行排序,同时重新排列每个嵌套列表以保留一般顺序。例如:

> unsorted <- list(a=data.frame(age=c(30,10,20), name=c("ann","bob","carl")), b=list("3x10","1x10","2x10"))
> unsorted
$a
  age name
1  30  ann
2  10  bob
3  20 carl

$b
$b[[1]]
[1] "3x10"

$b[[2]]
[1] "1x10"

$b[[3]]
[1] "2x10"

我希望按年龄排序

ord <- order(unsorted$a$age)

这就是诀窍:

sorted <- list(a=unsorted$a[ord,], b=unsorted$b[ord])
> sorted
$a
  age name
2  10  bob
3  20 carl
1  30  ann

$b
$b[[1]]
[1] "1x10"

$b[[2]]
[1] "2x10"

$b[[3]]
[1] "3x10"

这可以通过申请或其中一个化身来完成吗?

- 编辑 -

我的实际案例中的父列表有大量的子列表。所有子列表都包含N个对象,但这些对象具有可变结构。

2 个答案:

答案 0 :(得分:2)

如果我正确理解您的数据结构,那么您可以列出这些子列表,如下所示:

list_of_lists = list(unsorted, unsorted)

你只在问题中给出一个示例子列表,所以我假设

  • 你有一个像这样的大清单
  • 有1级嵌套,也就是说,您的子列表可能不包含更多需要排序的子列表,
  • 所有子列表都只有1个数据框,并且它有一个名为“age”的列,用于确定排序。

执行排序的写函数:

sort_list <- function(x) {
    df.index <- which(sapply(x, is.data.frame))
    stopifnot(length(df.index) == 1)
    ord <- order(x[[df.index]]$age)
    lapply(x, FUN = function(y) {
        if (is.data.frame(y)) return(y[ord, ])
        return(y[ord])
    }
    )
}

然后将lapply添加到您的列表列表中:

lapply(list_of_lists, sort_list)

编辑:

现在你已经澄清了你的数据结构,我认为要做的事情是先获取订单,然后lapply订购一切。

# Using your code to get the order:
ord <- order(unsorted$a$age)

lapply(unsorted, function(x, ord) {
      if (is.data.frame(x)) return(x[ord,])
      return(x[ord])
    },
    ord = ord
)

答案 1 :(得分:2)

您可以使用

lapply(unsorted, function(x) {
    if(is.vector(x)) x[order(unlist(x))] else x[order(x$age),]
})

$a
  age name
2  10  bob
3  20 carl
1  30  ann

$b
$b[[1]]
[1] "1x10"

$b[[2]]
[1] "2x10"

$b[[3]]
[1] "3x10"