首页 > 解决方案 > 如何通过自定义函数对列表进行排序,丢弃重复项?

问题描述

我有这个清单:

thresholds <- list(
     list(color="red", value=100),
     list(color="blue", value=50),
     list(color="orange", value=100),
     list(color="green", value=1),
     list(color="orange", value=50)
)

我想按每个元素的“值”字段对其进行排序并丢弃重复项,以便在结果列表中没有两个元素具有相同的“值”字段(当有平局时选择的元素无关紧要)。

sort并且unique不要使用复杂的列表,也不允许自定义排序。如何达到预期的效果?

标签: rsorting

解决方案


首先,在这种特殊情况下,要订购的实际向量是:

values <- sapply(thresholds, function (t) t$value)
# values == c(100, 50, 100, 1, 50)

您可以根据sapply需要调整内部功能(例如,根据您是要按数字还是字母顺序进行排序等进行适当的转换)。

从这一点来看,如果我们要保留重复项,答案很简单:

thresholds[order(values)]

order为“值”中的每个元素返回其排名,即如果向量已排序,则返回其位置。这里order(values)4 2 5 1 3。然后,返回由这些索引标识thresholds[order(values)]的元素,生成.thresholds1 50 50 100 100

但是,由于我们要删除重复项,所以不能这么简单。unique将不起作用thresholds,如果我们将其应用于values,它将失去与原始列表中索引的对应关系。

解决方案是使用另一个函数,即duplicated. 当应用于向量时,duplicated返回一个布尔向量,指示每个元素是否已存在于向量中较早位置的位置。例如,duplicated(values)将返回FALSE FALSE TRUE FALSE TRUE. 这个向量是我们在这里需要的重复元素的过滤器。

因此解决方案是:

ordering <- order(values)
nodups <- ordering[!duplicated(values)]
thresholds[nodups]

或作为单行:

thresholds[order(values)[!duplicated(values)]]

推荐阅读