【问题标题】:How to anti-sort data using R如何使用 R 对数据进行反排序
【发布时间】:2019-06-25 10:06:51
【问题描述】:

我不确定如何命名它,但如果我有一个值列表,例如:

set.seed(2084)
vals = round(runif(12, 1, 3))

[1] 2 3 2 2 1 1 3 2 1 2 2 2

我对它进行排序:

[1] 1 1 1 2 2 2 2 2 2 2 3 3

但我想得到类似交替排序的东西(取 1-2-3 并重复):

1 2 3 1 2 3 1 2 2 2 2 2

但问题是有 7 个二,它们在列表后面,而不是在其他值之间交替。我宁愿期望得到类似的东西:

1 2 2 3 1 2 2 2 1 2 2 3

1 2 2 3 1 2 2 3 1 2 2 2

如何索引它以获得这种“生长和切割”顺序的最均匀分布的值?

对我的想法发表一些看法。从这组 N 个唯一值(这里是 3 个)中,我们需要将它们中的每一个分布得尽可能远离彼此(以及远离该向量的边界)。因此,虽然我们有 1 个和 10 个插槽,但我们可以将它们放在这种模式中:

= 1 = = = 1 = = = 1

= = 1 = = 1 = = 1 =

这是正确的,除非其他数字在此列表中具有适当的位置。我们可以加三:

= 3 1 = = 1 = 3 1 =

现在,我们只有两个要填补。他们不会有理想的位置。我认为最好从值最丰富的数字开始。

我想清楚并描述一些算法,但我觉得反之亦然。

#编辑# 我猜对于较大的数据集,主题可能是“如何使用 R 在给定向量中均匀分布值”。如果反弹导致误解,也许这可能是从这种情况中安全退出的方式。但是在这里我不想有 2 个号码,除了有 5 个插槽可用。

对于1 2 2 3 4,有一个替代方案,例如1 2 3 4 2

编辑 2

我找到了一个适用于 2 个值的函数 - 这是半解决方案,但这个想法正在奏效。我认为它即将迭代超过 2 个值,但也许我错了。

不是很优雅

antisort <- function(vals) {
  l = length(unique(vals))
  mx = names(which.max(table(vals)))
  mn = names(which.min(table(vals)))
  mxn = max(table(vals))
  indx = round(seq(from = 1, to = length(vals), length.out = mxn))
  vec = NULL
  for (i in indx) {
    vec[i] <- mx
  }
  vec[which(is.na(vec))] <- mn
  return(vec)
}

数据:

set.seed(2201)
vals = round(runif(12, 1, 2))

运行:

antisort(vals)

结果(不管是字符串)

“2”“1”“2”“1”“2”“2”“1”“2”“1”“2”“1”“2”

【问题讨论】:

  • 我认为你需要更清楚或提供一些额外的例子。例如,为什么是1 2 2 3 1 2 2 2 1 2 2 3 而不是1 2 2 3 1 2 2 3 1 2 2 21 2 2 2 1 2 2 3 1 2 2 3
  • 您在寻找“正确”的答案吗?为什么1 2 2 3 1 2 2 2 1 2 2 3 而不是1 2 2 3 1 2 2 3 1 2 2 2?还是1 2 2 1 2 2 3 1 2 2 2 3?或者这些都很好,你不在乎哪一个?如果你的起始序列是1 1 1 2 2 3 3 3 3 3
  • 以上都很好,因为每个值都可能均匀分布。
  • 您知道将额外的 2 放在哪里的逻辑肯定令人困惑。 “在其他值之间交替”背后的数学(排序)原理是什么?
  • 什么决定了“重启”的次数——允许序列减少的次数?他们都需要从最低值开始吗?如果您的输入是1 2 2 2 2 2 2 3 3 3 3 3 3 4 4,那将是一个好的结果,还是您想要1 2 2 3 3 4 2 2 3 3 4 2 2 3 3?或者别的什么。

标签: r sorting


【解决方案1】:

其中一个可能是您所追求的:

rep_len(unique(vals), length(vals))

rep_len(sort(unique(vals)), length(vals))

【讨论】:

  • 这会改变频率。将table(vals)(3 个1s、7 个2s 和2 个3s 在OPs 输入中)与您的结果的table() 进行比较--每个4 个。
【解决方案2】:

这是一种可能的启发式方法:

set.seed(2084)
maxn <- 3
vals = round(runif(12, 1, maxn)) #integral values

#result vector
v <- rep(NA_character_, length(vals))

#tabulate frequencies and sort in descending order
lens <- sort(table(vals), decreasing=TRUE)

#going through each distinct integral values, starting with the longest one
for (x in names(lens)) {
    #cut the result vector into roughly lens[x] number of parts
    idx <- cut(seq_along(v), breaks=lens[x])

    #fill the first NA with the current integral value
    split(v, idx) <- lapply(split(v, idx), function(subv) {
        subv[which(is.na(subv))[1L]] <- x
        subv
    })
}

#split the vector into maxn number of parts and sort each group
#the hardest part is probably how many parts to split into, which is defaulted
#to maximum of integral values in the original vector
lapply(split(v, cut(seq_along(v), breaks=maxn, labels=1L:maxn)), sort)

输出:

$`1`
[1] "1" "2" "2" "3"

$`2`
[1] "1" "2" "2" "2"

$`3`
[1] "1" "2" "2" "3"

相关链接:https://cs.stackexchange.com/questions/29709/algorithm-to-distribute-items-evenly

【讨论】:

    猜你喜欢
    • 2017-03-26
    • 1970-01-01
    • 2020-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-13
    相关资源
    最近更新 更多