r - 检测有序字符串的序列并使用 R 对它们进行分组

标签 r string sequence

我有一个包含大约 50 万个元素的字符串向量,我想为每个元素分配一个值以显示每个元素的组号。

分组标准是这样的:

  • 从列表顶部连续分配一个组号
  • 应为每个元素分配不同的组,除非至少有 3 个连续元素按字母升序排列,其中这些连续元素将在一个组中。

我如何在 R 中执行此操作?

例如和预期的输出:

> my_strings <- c("xx1", "1xxx", "abc.xyz", "a", "ad022", "ghj1", "kf1", "991r",
+                 "jdd", "12vd", "r34o", "z", "034mh")
> expected_output <- c(1, 2, 3, 4, 4, 4, 4, 5, 6, 7, 7, 7, 8)
> (df <- data.frame(input = my_strings, output = expected_output))
     input output
1      xx1      1
2     1xxx      2
3  abc.xyz      3
4        a      4
5    ad022      4
6     ghj1      4
7      kf1      4
8     991r      5
9      jdd      6
10    12vd      7
11    r34o      7
12       z      7
13   034mh      8

到目前为止,我尝试使用 dplyr::lead 并根据两个连续元素分配顺序。不过,我不知道如何从这里开始。

res <- as_tibble(my_strings) %>%
  mutate(after = lead(my_strings))
res$pre_group = apply(res, 1, function(x) order(c(x[1], x[2]))[2])

最佳答案

(该死,这是一个艰难的过程:-)

整洁宇宙

library(dplyr)
df %>%
  mutate(r1 = cumsum(c(TRUE, diff(rank(input)) < 0)) + 0) %>%
  group_by(r1) %>%
  mutate(r2 = r1 + seq(0, 0.9*(n() < 3), len = n()) / n()) %>%
  ungroup() %>%
  mutate(r1 = with(list(rl = rle(r2)$lengths), rep(seq_along(rl), times = rl))) %>%
  select(-r2)
# # A tibble: 13 x 3
#    input   output    r1
#    <chr>    <dbl> <int>
#  1 xx1          1     1
#  2 1xxx         2     2
#  3 abc.xyz      3     3
#  4 a            4     4
#  5 ad022        4     4
#  6 ghj1         4     4
#  7 kf1          4     4
#  8 991r         5     5
#  9 jdd          6     6
# 10 12vd         7     7
# 11 r34o         7     7
# 12 z            7     7
# 13 034mh        8     8

(mutate 中冗长的 with(...) 只是 data.table::rleid 的内联版本。)

数据表

library(data.table)
as.data.table(df)[
, r1 := cumsum(c(TRUE, diff(rank(input)) < 0)) + 0 ][
, r1 := r1 + seq(0, 0.9*(.N < 3), len = .N), by = .(r1) ][
, r1 := rleid(r1) ]

如果你想稍微模糊一下 R 方言的界线,那么

library(data.table)
library(magrittr)
as.data.table(df) %>%
  .[, r1 := cumsum(c(TRUE, diff(rank(input)) < 0)) + 0 ] %>%
  .[, r1 := r1 + seq(0, 0.9*(.N < 3), len = .N), by = .(r1) ] %>%
  .[, r1 := rleid(r1) ]

注意事项:

  • ... + 0as.numeric(...) 的简写。这是因为 data.table 在更新列时强制执行列的原始 class;由于 r1 的第一个定义(没有 +0)将是 integerr1 的下一次重新分配返回 数字。然而,由于 data.table 保留了原始类,数字将被强制(截断)为整数,我的努力停止了。

  • seq(0, 0.9*(...)) 减少为 seq(0,0) 当一个组中有三个或更多时,这会导致该组无操作。 (这使用 dplyrn()data.table.N 来确定组大小。 )

  • 实现略有不同,因为 dplyr 禁止修改分组变量; data.table 对此没有问题。 (我不确定哪个方向是正确的或更好的......)

关于r - 检测有序字符串的序列并使用 R 对它们进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63291964/

相关文章:

r - 在 R 中创建一元运算符

r - 获取一定长度的连续整数的运行并从第一个值中采样

sql - 使用RSQLite直接使用SQL操作r中的数据框

r - ggplot2 中的中心图标题

java - 如何在 Java 中逐步解码大型多字节字符串文件?

ruby - 如何从 Ruby 中特定索引处的字符串中删除字符

c - 如何将不同长度的字符串放入指针中,例如 char *output[100]

python - 按日期拆分或合并操作

Python:如何生成一个序列,每个 m 个数字跳过 n 个数字

r - S3中的美元建议方法