首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R-基于模式提取字符串

R-基于模式提取字符串
EN

Stack Overflow用户
提问于 2017-08-07 09:18:40
回答 3查看 173关注 0票数 0

我有一个矢量数据(这是数据框中的一列):

代码语言:javascript
复制
 [1] "Tue 12-14 (w1-6, CLB 6)"           "Mon 18-20 (w1-6, ColomboThC)"      "Thu 14-16 (w1-6,7-9,10-12, CLB 8)"
 [4] "Fri 13 (w2-9,10-13, Law 388)"      "Fri 14 (w2-9,10-13, Sqhouse206)"   "Fri 15 (w2-9,10-13, Sqhouse115)"  
 [7] "Thu 17 (w2-9,10-13, Block G16)"    "Thu 18 (w2-9,10-13, Block G16)"    "Mon 10 (w2-9,10-13, AinswthG01)"  
[10] "Mon 11 (w2-9,10-13, Sqhouse203)"   "Mon 12 (w2-9,10-13, Sqhouse206)"   "Mon 13 (w2-9,10-13, BUS 114)"     
[13] "Mon 16 (w2-9,10-13, Gold G03)"     "Mon 17 (w2-9,10-13, Quad G047)"    "Mon 20 (w2-9,10-13, Col LG02)"    
[16] "Tue 17 (w2-9,10-13, Quad 1001)"    "Tue 18 (w2-9,10-13, Quad 1001)"    "Tue 19 (w2-9,10-13, Quad 1001)"   
[19] "Tue 20 (w2-9,10-13)"               "Wed 10 (w2-9,10-13, Quad 1046)"    "Wed 11 (w2-9,10-13, Quad 1046)"   
[22] "Wed 12 (w2-9,10-13, Quad 1046)"    "Wed 13 (w2-9,10-13, Quad G046)"

我想根据模式提取字符串,因此,作为示例,向量的第一个元素的预期输出为:

代码语言:javascript
复制
"Tue" "12-14"  "1-6" "CLB 6"

第三个元素的输出示例如下:

代码语言:javascript
复制
 "Thu" "14-16" c("1-6","7-9","10-12") "CLB 8"

其中c("1-6","7-9","10-12")是一个列表。

(请注意,其中的每一个都将作为新列附加到我的数据框中。)

我正在考虑使用gsub来提取字符串的每一部分。还有没有其他我可以使用的函数?

任何建议都是非常感谢的:)

EN

回答 3

Stack Overflow用户

发布于 2017-08-07 10:30:03

我们可以尝试使用tidyverse中的函数

代码语言:javascript
复制
library(tidyverse)
str_split_fixed(vec, pattern = " ", n = 3) %>% 
  as.data.frame() %>%
  mutate(V3 = str_sub(V3,3,-2)) %>%
  separate(V3, c("V3", "V4"), sep = ", ")

代码编写如下:

  1. 通过一个空格将向量vec拆分为3列,并将其强制为第三列中的dataframe.
  2. Extract字符串,以排除左方括号和右方括号以及“w”。
  3. 使用", ".

分隔第三列

输出示例:

代码语言:javascript
复制
   V1    V2            V3         V4
1 Tue 12-14           1-6      CLB 6
2 Mon 18-20           1-6 ColomboThC
3 Thu 14-16 1-6,7-9,10-12      CLB 8
票数 2
EN

Stack Overflow用户

发布于 2017-08-07 13:06:58

在结尾处的注释中使用输入x

将每个字符串中的第一个空格替换为分号,将下一个空格及其后面的两个字符替换为分号,将下一次出现的逗号替换为最后一个在数据框中使用逗号的character

  • read将第3列的字段拆分为使用逗号的字符向量列表--如果您希望字符串而不是作为第3列

列出,请省略此步骤

它只使用单独的简单步骤,没有包。

代码语言:javascript
复制
y <- x
y <- sub(" ", ";", y)
y <- sub(" ..", ";", y)
y <- sub(", ", ";", y)
y <- sub(".$", "", y)
DF <- read.table(text = y, sep = ";", as.is = TRUE, fill = NA)
DF[[3]] <- strsplit(DF[[3]], ",")

给予:

代码语言:javascript
复制
> DF
    V1    V2              V3         V4
1  Tue 12-14             1-6      CLB 6
2  Mon 18-20             1-6 ColomboThC
3  Thu 14-16 1-6, 7-9, 10-12      CLB 8
4  Fri    13      2-9, 10-13    Law 388
5  Fri    14      2-9, 10-13 Sqhouse206
6  Fri    15      2-9, 10-13 Sqhouse115
7  Thu    17      2-9, 10-13  Block G16
8  Thu    18      2-9, 10-13  Block G16
9  Mon    10      2-9, 10-13 AinswthG01
10 Mon    11      2-9, 10-13 Sqhouse203
11 Mon    12      2-9, 10-13 Sqhouse206
12 Mon    13      2-9, 10-13    BUS 114
13 Mon    16      2-9, 10-13   Gold G03
14 Mon    17      2-9, 10-13  Quad G047
15 Mon    20      2-9, 10-13   Col LG02
16 Tue    17      2-9, 10-13  Quad 1001
17 Tue    18      2-9, 10-13  Quad 1001
18 Tue    19      2-9, 10-13  Quad 1001
19 Tue    20      2-9, 10-13           
20 Wed    10      2-9, 10-13  Quad 1046
21 Wed    11      2-9, 10-13  Quad 1046

可以用这一行代码替换前4行代码,在这种情况下,总共只有4行代码。

代码语言:javascript
复制
y <- Reduce(function(x, pat) sub(pat, ";", x), init = x, c(" ", " ..", ", "))

注意:可复制形式的输入x为:

代码语言:javascript
复制
x <- c("Tue 12-14 (w1-6, CLB 6)", "Mon 18-20 (w1-6, ColomboThC)", 
"Thu 14-16 (w1-6,7-9,10-12, CLB 8)", "Fri 13 (w2-9,10-13, Law 388)", 
"Fri 14 (w2-9,10-13, Sqhouse206)", "Fri 15 (w2-9,10-13, Sqhouse115)", 
"Thu 17 (w2-9,10-13, Block G16)", "Thu 18 (w2-9,10-13, Block G16)", 
"Mon 10 (w2-9,10-13, AinswthG01)", "Mon 11 (w2-9,10-13, Sqhouse203)", 
"Mon 12 (w2-9,10-13, Sqhouse206)", "Mon 13 (w2-9,10-13, BUS 114)", 
"Mon 16 (w2-9,10-13, Gold G03)", "Mon 17 (w2-9,10-13, Quad G047)", 
"Mon 20 (w2-9,10-13, Col LG02)", "Tue 17 (w2-9,10-13, Quad 1001)", 
"Tue 18 (w2-9,10-13, Quad 1001)", "Tue 19 (w2-9,10-13, Quad 1001)", 
"Tue 20 (w2-9,10-13)", "Wed 10 (w2-9,10-13, Quad 1046)", "Wed 11 (w2-9,10-13, Quad 1046)", 
"Wed 12 (w2-9,10-13, Quad 1046)", "Wed 13 (w2-9,10-13, Quad G046)"
票数 1
EN

Stack Overflow用户

发布于 2017-08-07 11:21:57

Base函数可以做的,你不需要导入任何其他的包。tidyverse是一个很好的工具,但是对于这个来说有点大了,

代码语言:javascript
复制
x=c("Thu 18 (w2-9,10-13, Block G16)","Mon 18-20 (w1-6, ColomboThC)")
do.call(rbind,lapply(x,function(i){
  y=strsplit(i,' \\(')[[1]]
  y[2]=gsub('\\)','',y[2])
  out1=strsplit(y[1],' ')[[1]]
  out2=strsplit(y[2],', ')[[1]]
  listpart=grepl('-',out2)
  do.call(cbind,c(out1,list(out2[listpart]),out2[!listpart]))
}))

输出将为:

代码语言:javascript
复制
         [,1]  [,2]    [,3]         [,4]        
[1,] "Thu" "18"    "w2-9,10-13" "Block G16" 
[2,] "Mon" "18-20" "w1-6"       "ColomboThC"
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45538184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档