首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从R中的复杂字符串中提取多个新列(str_sub似乎做不到这一点)

如何从R中的复杂字符串中提取多个新列(str_sub似乎做不到这一点)
EN

Stack Overflow用户
提问于 2016-09-07 21:55:37
回答 2查看 162关注 0票数 2

我很难从R中的字符串中提取多个变量。

列如下所示:

7 digit identifier_NAME4 digit value-4 digit value-4 digit value-location1-location27-digit identifier_junk_junk_3 digit value with junk attached

例如:

代码语言:javascript
复制
1234567_NAME:0011-1234-0176-town-car:1234567_000001_original_010qyz

我需要有以下内容的新专栏:

  • 7位标识符("1234567")
  • 名字
  • 4位数值中的每一位
  • 每一地点
  • 3位数值

str_sub()无法工作,因为字符串的某些部分的长度是可变的。

我尝试了gsub,但是由于一些特殊字符被多次重复(即":‘和"-"),所以我无法使用它们提取字符串的一个定义良好的部分。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-09-07 22:10:13

为了避免冗长的正则表达式,一个选项是使用str_split_fixed作为分隔符,将列拆分成一个矩阵,删除不需要的列,并从最后一列中提取数值:

代码语言:javascript
复制
s <- "1234567_NAME:0011-1234-0176-town-car:1234567_000001_original_010qyz"
ss <- c(s,s,s)

library(stringr)
mat <- str_split_fixed(ss, "[_:-]", 11)[,-c(9, 10)]
mat
#     [,1]      [,2]   [,3]   [,4]   [,5]   [,6]   [,7]  [,8]      [,9]    
#[1,] "1234567" "NAME" "0011" "1234" "0176" "town" "car" "1234567" "010qyz"
#[2,] "1234567" "NAME" "0011" "1234" "0176" "town" "car" "1234567" "010qyz"
#[3,] "1234567" "NAME" "0011" "1234" "0176" "town" "car" "1234567" "010qyz"

mat[,9] <- sub("(\\d{3}).*", "\\1", mat[,9])
mat
#     [,1]      [,2]   [,3]   [,4]   [,5]   [,6]   [,7]  [,8]      [,9] 
#[1,] "1234567" "NAME" "0011" "1234" "0176" "town" "car" "1234567" "010"
#[2,] "1234567" "NAME" "0011" "1234" "0176" "town" "car" "1234567" "010"
#[3,] "1234567" "NAME" "0011" "1234" "0176" "town" "car" "1234567" "010"
票数 1
EN

Stack Overflow用户

发布于 2016-09-07 22:15:46

如果您保留“冗长”正则表达式,那么您可以这样做(并在后面添加记录验证,因为您已经嵌入了字段长度):

代码语言:javascript
复制
library(stringi)
library(purrr)

pat <- "(.{7})_([[:alnum:][:space:]]+):([[:digit:]]{4})-([[:digit:]]{4})-([[:digit:]]{4})-([[:alnum:][:space:]]+)-([[:alnum:][:space:]]+):([[:digit:]]{7})_[[:alnum:][:space:]]+_[[:alnum:][:space:]]+_([[:digit:]]{3})"

dat <- "1234567_NAME:0011-1234-0176-town-car:1234567_000001_original_010qyz"
dat <- rep(dat, 10)

cols <- c("id", "name", "val1", "val2", "val3", "loc1", "loc2", "val3")

stri_match_all_regex(dat, pat) %>% 
  map_df(~setNames(as.list(.[,c(2:8,10)]), cols))
## # A tibble: 10 x 7
##         id  name  val1  val2  val3  loc1  loc2
##      <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1  1234567  NAME  0011  1234   010  town   car
## 2  1234567  NAME  0011  1234   010  town   car
## 3  1234567  NAME  0011  1234   010  town   car
## 4  1234567  NAME  0011  1234   010  town   car
## 5  1234567  NAME  0011  1234   010  town   car
## 6  1234567  NAME  0011  1234   010  town   car
## 7  1234567  NAME  0011  1234   010  town   car
## 8  1234567  NAME  0011  1234   010  town   car
## 9  1234567  NAME  0011  1234   010  town   car
## 10 1234567  NAME  0011  1234   010  town   car
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39379598

复制
相关文章

相似问题

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