通过以相似模式匹配两列来分隔行

时间:2019-08-06 12:26:36

标签: r tidyverse

我有类似

的数据
df1 <- data.frame(A = c("P,Q","X,Y"), B = c("P1,Q1",""), C = c("P2,Q2","X2,Y2"))

我正在寻找类似的输出

output <- data.frame(A = c("P","Q","X","Y"), B = c("P1","Q1","",""), C = c("P2","Q2","X2","Y2"))

我尝试使用如下面提到的split_rows,但是它与以逗号分隔的字符串不匹配。

separate_rows(df1, A, sep=",") %>%
  separate_rows(B) %>%
  separate_rows(C)

4 个答案:

答案 0 :(得分:2)

您只需要做:

library(tidyr)
separate_rows(df1, A, B, C, convert = TRUE)

输出:

  A  B  C
1 P P1 P2
2 Q Q1 Q2

如果您有NA和空字符串,则进行编辑:

data:
df1 <- data.frame(A = c("P,Q","X,Y"), B = c("P1,Q1",""), C = 
c("P2,Q2","X2,Y2"))


Code:

df1 <- data.frame(lapply(df1, as.character), stringsAsFactors=FALSE)
df1[df1 == ""] <- "0,0"
df1 <- separate_rows(df1, A, B, C, convert = TRUE)
df1[df1 == "0"] <- ""

输出:

  A  B  C
1 P P1 P2
2 Q Q1 Q2
3 X    X2
4 Y    Y2

答案 1 :(得分:2)

我喜欢splitstackshape软件包进行此类操作,

library(splitstackshape)

cSplit(df1, splitCols = names(df1), sep = ',', direction = 'long')
#   A  B  C
#1: P P1 P2
#2: Q Q1 Q2

答案 2 :(得分:0)

base Rstrsplit一起使用的选项

data.frame(lapply(df1, function(x) strsplit(as.character(x), ",")[[1]]))
#   A  B  C
#1 P P1 P2
#2 Q Q1 Q2

或与scan

data.frame(lapply(df1, function(x) 
     scan(text = as.character(x), what = "", sep=",", quiet = TRUE)))

答案 3 :(得分:0)

正如Gainz的答案所建议的那样,separate_rows(df1, A, B, C, convert = T)的确非常有效。

但是,如果数据框中确实有空白单元格,那么它将变得更难使用,因为它将使您对所有不具有相同行数的列产生错误。

我建议使用您知道没有空白值的列。假设它是A列。

然后我首先将数据帧转换为小标题,然后将所有因子列转换为字符列。然后,我将用正确数量的逗号替换字符串中的空白单元格。然后separate_rows()应该可以正常工作。

然后代码将如下所示:


df1_tibble <- df1 %>% 
  as_tibble() %>% 
  mutate_if(is.factor, as.character)

df1_clean <- df1_tibble %>% 
  mutate(count = str_count(A, ",") + 1) %>% 
  mutate(temp_str = map_chr(count, ~ rep("", .x) %>% paste0(collapse = ","))) %>% 
  mutate_at(vars(B, C), funs(ifelse(str_length(.) == 0, temp_str, .))) %>% 
  select(A, B, C)

df1_clean
#> # A tibble: 2 x 3
#>   A     B     C    
#>   <chr> <chr> <chr>
#> 1 P,Q   P1,Q1 P2,Q2
#> 2 X,Y   ,     X2,Y2

df1_clean %>% separate_rows(A, B, C)
#> # A tibble: 4 x 3
#>   A     B     C    
#>   <chr> <chr> <chr>
#> 1 P     P1    P2   
#> 2 Q     Q1    Q2   
#> 3 X     ""    X2   
#> 4 Y     ""    Y2