下面是一个转换的简化表示,我需要将它应用于一个大型复杂表。在这里,输入表是一个有两个数字列的查找。raw和SS有着多对一的关系.raw的许多值可以具有相同的SS值,但反之亦然。
library(tidyverse)
input <- tribble(
~raw, ~SS,
0, 75,
1, 78,
2, 80,
3, 83,
4, 83,
5, 83,
6, 90,
7, 93,
8, 95,
9, 98
)所需的输出表如下。
output <- tribble(
~SS, ~raw,
100, '-',
99, '-',
98, '9',
97, '-',
96, '-',
95, '8',
94, '-',
93, '7',
92, '-',
91, '-',
90, '6',
89, '-',
88, '-',
87, '-',
86, '-',
85, '-',
84, '-',
83, '3-5',
82, '-',
81, '-',
80, '2',
79, '-',
78, '1',
77, '-',
76, '-',
75, '0',
74, '-',
73, '-',
72, '-',
71, '-',
70, '-'
)要创建此输出,需要通过以下几种方式转换输入:
SS列填充了所有缺失的整数(70:100),并按降序排序。raw列强制使用字符,有三种类型的值来保留原始SS:的多对一关系。SS的值,没有对应的raw值(例如,SS = 70)SS值的单个值(例如,'2'),其对应值为raw (例如,SS = 80)SS值的范围(例如,'3-5') (例如,SS = 83)
以下是我在这方面取得的成就:
interim <- input %>% select(
SS, raw
) %>%
mutate_at(
vars(
raw
), ~ as.character(.x)
) %>%
complete(
SS = 70:100
) %>%
arrange(
desc(
SS
)
) %>%
mutate_at(
vars(
raw
), ~ case_when(
is.na(.x) ~ '-',
TRUE ~ .x
)
)如果您运行上述代码,您将看到唯一剩下的转换是将三行SS = 83行折叠为一行,其中对应的raw值为'3-5'。这意味着以某种方式认识到3和5是范围的下界和上界,因为解将需要处理不确定长度的连续整数的范围。
提前感谢您的帮助!
发布于 2019-07-11 00:09:11
一个选项是complete,然后执行group_by paste
library(tidyverse)
out1 <- input %>%
complete(SS = 70:100, fill = list(raw = '-')) %>%
group_by(SS) %>%
summarise(raw = if(n() > 1) str_c(range(raw), collapse='-') else raw) %>%
arrange(desc(SS))
out1
# A tibble: 31 x 2
# SS raw
# <dbl> <chr>
# 1 100 -
# 2 99 -
# 3 98 9
# 4 97 -
# 5 96 -
# 6 95 8
# 7 94 -
# 8 93 7
# 9 92 -
#10 91 -
# … with 21 more rows带OP输出的-checking
identical(out1, output)
#[1] TRUE或在filter之前使用group_by后的paste步骤。
input %>%
complete(SS = 70:100, fill = list(raw = '-')) %>%
group_by(SS) %>%
filter(n() == 1| n() > 1 & row_number() %in% c(1, n())) %>%
summarise(raw = str_c(raw, collapse = '-')) %>%
arrange(desc(SS))发布于 2019-07-10 23:54:50
有一种方法-
tibble(SS = 100:70) %>%
left_join(input, by = "SS") %>%
replace_na(list(raw = "-")) %>%
group_by(SS) %>%
summarize(raw = paste0(unique(range(raw)), collapse = "-")) %>%
arrange(desc(SS))
# A tibble: 31 x 2
SS raw
<dbl> <chr>
1 100 -
2 99 -
3 98 9
4 97 -
5 96 -
6 95 8
7 94 -
8 93 7
9 92 -
10 91 -
11 90 6
12 89 -
13 88 -
14 87 -
15 86 -
16 85 -
17 84 -
18 83 3-5
19 82 -
20 81 -
21 80 2
22 79 -
23 78 1
24 77 -
25 76 -
26 75 0
27 74 -
28 73 -
29 72 -
30 71 -
31 70 - 发布于 2019-07-11 03:25:19
data.table解决方案:
input_dt[, .(raw = ifelse(.N == 1, as.character(raw), paste(min(raw), max(raw), sep = '-'))), by = SS
][data.table(SS = 70:100), on = 'SS'
][is.na(raw), raw := '-'
][order(-SS)]和base
out_2 <- merge(data.frame(SS = 70:100)
, aggregate(raw ~ SS
, data = input
, FUN = function(x) ifelse(length(x) == 1, as.character(x), paste(min(x), max(x), sep = '-')))
, by = 'SS'
, all.x = TRUE
)
out_2$raw <- ifelse(is.na(out_2$raw), '-', out_2$raw)
out_2[order(-out_2$SS), ]数据:
library(tibble)
input <- tribble(
~raw, ~SS,
0, 75,
1, 78,
2, 80,
3, 83,
4, 83,
5, 83,
6, 90,
7, 93,
8, 95,
9, 98
)
library(data.table)
input_dt <- as.data.table(input)https://stackoverflow.com/questions/56979935
复制相似问题