首页 > 解决方案 > 如何在 R 中优化此代码(将字符串拆分为列)

问题描述

我有这个有效的 R 代码:

df <- data.frame(C1=c('[AU 1] string 1; [AU 2] string 2; [AU 3] string 3.1; string 3.2; [AU 4] string 
4.1; string 4.2; [AU 5] string 5','[AU 1; AU 2] string 1','[AU 1] string 1; [AU 2] string 2'), 
UT=c("A1","A2","A3"))

s <-strsplit(df$C1, split = "(; (?=\\[))",perl=TRUE)

df1<-data.frame(
UT= rep(df$UT, sapply(s, length)),
AU=gsub('] .*', ']', unlist(s)),
C1=gsub('.*\\]', '', unlist(s)))

s1 <-strsplit(df1$C1, split = "; ",perl=TRUE)

df2<-data.frame(
UT= rep(df1$UT, sapply(s1, length)),
AU= rep(df1$AU, sapply(s1, length)),
C1=unlist(s1))

如何让这段代码更有效率,有什么想法吗?

obs:基地有超过100万行。

标签: rstringdataframe

解决方案


我们可以使用separate_rows;后跟零个或多个空格 ( \\s*) 后跟左方括号 ( [) 分割“C1”(因为;在 中[],我们希望避免分割该部分)。然后在扩展数据上,最好使用str_extract从左方括号中获取字符的子字符串,直到]在 'AU' 中结束,然后提取所有以 'string' 开头的子字符串,后跟任何空格和一些数字.。作为str_extract_all返回 a list,我们unnestlist列执行 an 以将其转换为普通列

library(dplyr)
library(tidyr)
library(stringr)
df %>% 
   separate_rows(C1, sep=";\\s*(?=\\[)") %>%
   mutate(AU = str_extract(C1, "\\[[^]]+\\]"), 
        C1 = str_extract_all(C1, 'string\\s*[0-9.]+')) %>% 
   unnest(c(C1)) %>%
   select(UT, AU, C1)

-输出

# A tibble: 10 x 3
#   UT    AU           C1        
#   <chr> <chr>        <chr>     
# 1 A1    [AU 1]       string 1  
# 2 A1    [AU 2]       string 2  
# 3 A1    [AU 3]       string 3.1
# 4 A1    [AU 3]       string 3.2
# 5 A1    [AU 4]       string 4.1
# 6 A1    [AU 4]       string 4.2
# 7 A1    [AU 5]       string 5  
# 8 A2    [AU 1; AU 2] string 1  
# 9 A3    [AU 1]       string 1  
#10 A3    [AU 2]       string 2  

推荐阅读