在 R 中对一个大小不等的向量列表进行排序

6
假设我有几个向量 - 也许它们存储在一个列表中,但如果有更好的数据结构也可以:
ll <- list(c(1,3,2),
           c(1,2),
           c(2,1),
           c(1,3,1))

我希望对它们进行排序,按照第一个数字,然后使用第二个数字解决绑定,然后使用第三个数字解决剩余的绑定,以此类推。

c(1,2)
c(1,3,1)
c(1,3,2)
c(2,1)

有没有内置的函数可以让我做到这一点,还是需要自己编写解决方案?

(对于那些了解Python的人来说,我想要的是类似于Python中sort函数的行为)


2
这就是你要找的“字典序”。 - Falko
只是要注意(我应该在问题中明确说明):每个向量的元素可能不止一个数字,例如一个向量可以是c(1,10,1)。 - RobinL
为了使您的排序有意义,所有向量都应具有相同的长度(即,填充NA值)。在这种情况下,matrixdata.frame将是合理的数据结构。我的答案假设您不想更改您的向量。 - Roland
@Roland:为什么使用可变向量长度进行排序没有意义?百科全书中的单词顺序不遵循同样的原则吗? - Falko
我不确定是否同意仅当所有向量长度相同时排序才有意义的想法。我正在尝试制作一个扑克程序,将此处的Python代码翻译成R以查看其运行情况:https://www.udacity.com/wiki/cs212/unit-1。该链接中的程序使用长度不相等的向量来计算手牌的顺序(请参见“Poker问题的完整代码”),我认为这是对排序长度不相等的向量的有意义的应用案例。话虽如此,我同意在R中解决此问题似乎最容易使所有向量具有相同的长度。 - RobinL
我们这里不涉及词典顺序,而是数字排序。在这种情况下,对于长度不相等的向量进行排序的概念似乎有些奇怪。但你的看法可能不同。 - Roland
2个回答

6
ll <- list(c(1,3,2),
           c(1,2),
           c(2,1),
           c(1,3,1))

我更喜欢使用NA来表示缺失值,而不是使用paste,并且使用rbind.data.frame
sortfun <- function(l) {
  l1 <- lapply(l, function(x, n) {
    length(x) <- n
    x
  }, n = max(lengths(l)))
  l1 <- do.call(rbind.data.frame, l1)
  l[do.call(order, l1)] #order's default is na.last = TRUE
}

sortfun(ll)

#[[1]]
#[1] 1 2
#
#[[2]]
#[1] 1 3 1
#
#[[3]]
#[1] 1 3 2
#
#[[4]]
#[1] 2 1

1
不错。我想这行代码的改进可能是 ll[do.call(order,lapply(seq_len(max(lengths(ll))),function(x) vapply(ll,"[",FUN.VALUE=1,x)))],在这个过程中不需要构建一个 data.frame - nicola
谢谢。在观看这个线程的同时,我试图创建自己的解决方案。它与你的类似,但我真的很喜欢你的 length(x) <- n 技巧,我之前没有意识到这是可能的。我也不知道你可以使用 rbind.data.frame(我需要分成两步来完成)。 - RobinL

1
这里有一种使用data.table的方法。
结果是一个矩形data.table,行按您描述的形式排序。NA值用于填充列表项长度不同的情况。
library(data.table)
setorderv(data.table(do.call(cbind, transpose(l))), paste0("V", 1:max(lengths(l))))[]
#    V1 V2 V3
# 1:  1  2 NA
# 2:  1  3  1
# 3:  1  3  2
# 4:  2  1 NA

这看起来很丑,但你可以像这样在列表中使用结果:
l[setorderv(
  data.table(
    do.call(cbind, transpose(l)))[
      , ind := seq_along(l)][], 
  paste0("V", seq_len(max(lengths(l)))))$ind]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接