簡體   English   中英

在復雜數據的情況下如何分隔行

[英]how to separate_rows in case of a complex data

說真的,這個問題本來不是我的。 這個問題促使我把它放在一個簡化的案例中。

因此,我必須根據分隔符將輸入到單元格(列中)的數據分成單獨的行; 在目前的情況下。 這可以使用tidyr::separate_rows()輕松完成。 幾乎列中的數據已經連接。 現在的問題,實際上是兩個,是——

  1. 可能有文本由;分隔但可能在右括號()內,例如(text_A;text_B)將被連接起來而不是分開。
  2. 每行中不同列的單元格之間可能存在奇數個串聯。 在這種情況下,該行將被分成等於最大連接數的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM