![](/img/trans.png)
[英]How to apply separate_rows() to all columns, passing a `sep` parameter?
[英]how to separate_rows in case of a complex data
說真的,這個問題本來不是我的。 這個問題促使我把它放在一個簡化的案例中。
因此,我必須根據分隔符將輸入到單元格(列中)的數據分成單獨的行;
在目前的情況下。 這可以使用tidyr::separate_rows()
輕松完成。 幾乎列中的數據已經連接。 現在的問題,實際上是兩個,是——
;
分隔但可能在右括號()
內,例如(text_A;text_B)
將被連接起來而不是分開。separate rows
。 對於連接較少的其他列,最后一個 text_value 可能只是重復。一個可重現的例子如下
input <- data.frame(
stringsAsFactors = FALSE,
col_1 = c("A", "B", "C"),
Col_2 = c("Text_A;Text_B","Text_C","Text_D;(Text_E;Text_F)"),
Col_3 = c("Text_1", "Text_2;Text_3", "Text_4"),
Col_4 = c("Text_a;(Text_b;Text_c);(Text_d;Text_dd)","Text_e","Text_f;Text_g")
)
input
col_1 Col_2 Col_3 Col_4
1 A Text_A;Text_B Text_1 Text_a;(Text_b;Text_c);(Text_d;Text_dd)
2 B Text_C Text_2;Text_3 Text_e
3 C Text_D;(Text_E;Text_F) Text_4 Text_f;Text_g
所需的 output 如下:
output
#> col_1 Col_2 Col_3 Col_4
#> 1 A Text_A Text_1 Text_a
#> 2 A Text_B Text_1 (Text_b;Text_c)
#> 3 A Text_B Text_1 (Text_d;Text_dd)
#> 4 B Text_C Text_2 Text_e
#> 5 B Text_C Text_3 Text_e
#> 6 C Text_D Text_4 Text_f
#> 7 C (Text_E;Text_F) Text_4 Text_g
tidyverse
以外的答案也是可以接受的。
這是我的方法,僅假設您的列中沒有序列"<sep>"
:
input %>%
mutate(across(-col_1,
~ str_replace_all(., "\\([^)]*\\)",
\(x) str_replace_all(x, ";", "<sep>")))) %>%
pmap(\(...) {
args <- list(...)
entries <- map(args[-1], ~ first(str_split(., ";")))
map(entries, \(e) {
c(e, rep(e[length(e)], do.call(max, map(entries, length)) - length(e)))
}) %>%
bind_rows() %>%
bind_cols(args[1], .)
}) %>%
bind_rows() %>%
mutate(across(-col_1, ~ str_replace_all(., "<sep>", ";")))
回報:
# A tibble: 7 x 4
col_1 Col_2 Col_3 Col_4
<chr> <chr> <chr> <chr>
1 A Text_A Text_1 Text_a
2 A Text_B Text_1 (Text_b;Text_c)
3 A Text_B Text_1 (Text_d;Text_dd)
4 B Text_C Text_2 Text_e
5 B Text_C Text_3 Text_e
6 C Text_D Text_4 Text_f
7 C (Text_E;Text_F) Text_4 Text_g
提取通緝組。 計算每行的最大長度並填充值。
input <- input %>%
mutate(across(everything(), str_extract_all, pattern = "(\\([^\\(\\)]+\\)|[^;]+)"))
input_l <- pmap_int(input, ~max(map_int(list(...), length)))
input %>%
split(seq_len(nrow(.))) %>%
map(flatten) %>%
map2_dfr(input_l, function(row, l) map_dfr(row, ~c(.x, rep(last(.x), l - length(.x)))))
這給出了以下 output
col_1 Col_2 Col_3 Col_4
<chr> <chr> <chr> <chr>
1 A Text_A Text_1 Text_a
2 A Text_B Text_1 (Text_b;Text_c)
3 A Text_B Text_1 (Text_d;Text_dd)
4 B Text_C Text_2 Text_e
5 B Text_C Text_3 Text_e
6 C Text_D Text_4 Text_f
7 C (Text_E;Text_F) Text_4 Text_g
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.