【发布时间】:2021-05-15 04:28:47
【问题描述】:
我正在尝试读取另一组的数据,其中有一列通常用逗号分隔一对两个数字,但在大约 10% 的情况下 (>15,000) 没有逗号。手动分离太多了,但我在设计一种有效分离字符串的有效方法时遇到了麻烦。以下是规则:
- 字符串为 5 或 6 个字符,对应两个数字,每个数字为 2 或 3 个字符
- 如果你把这两个数字相加,总和大约是 150 到 250
- 任一侧的最大值为 150
- 各个值应一起最大化,例如id = 8 将是 101 和 48 而不是 10 和 148,如果有平局,则选择具有最大小值的对,例如11121 应该是 111 和 21 而不是 11 和 121
这是一个示例:
tribble(
~id, ~to_split,
1, 33118,
2, 37118,
3, 30121,
4, 41110,
5, 98121,
6, 101102,
7, 101110,
8, 10148,
9, 11121
) %>%
mutate_at("to_split", as.character)
这是我想要得到的结果:
tribble(
~id, ~left, ~right,
1, 33, 118,
2, 37, 118,
3, 30, 121,
4, 41, 110,
5, 98, 121,
6, 101, 102,
7, 101, 110,
8, 101, 48,
9, 111, 21
)
我曾考虑将它们分成两个不同的配对,方法是取前两个字符和其余字符、前三个字符和其余字符,然后将这两个配对相加,看看哪个总和最小。虽然我认为这种启发式方法适用于所有事情,但实施起来有点痛苦。我在这里考虑进行两个separate 调用(保持= TRUE),然后大概pivot_long 和group_by id 以便filter 正确的选项。有更简单的选择吗?
理想情况下,我想在 mutate 中完成这一切(可能需要 purrr::map?),但我不确定如何按位置拆分字符串并获取它的两个部分(没有 separate)。如果可能的话,应该是case_when/ifelse 来确定哪个配对更小,然后在它们之间的正确位置添加逗号或其他分隔符,这样我就可以bind_rows 回到剩下的我会separate 一切。但我发现分离字符串并获取两个部分的唯一方法是separate。来自stringr 或stringi 的东西会这样做吗?
【问题讨论】:
-
您能否解释一下 id 9 的逻辑,选择 111 + 21 而不是 11 + 121?
-
是的,这是一个奇怪的边缘案例,老实说可能是其中之一,我无法知道,因为我正试图从数据和知识中找出这个小组围绕这些数字的规则场地。考虑到它们所代表的含义,拥有符合规则的最高个人数字“更好”,因此选择 21 比 11 更好(尽管有 11105,所以 11 必须是可能的,因为 05 很奇怪而且更糟)。如果这还不够清楚,四分之二,lmk 和我会尝试更好地表达它。