如何在r语言中按第n个字符拆分字符串

4

我正在处理以下数据:

District <- c("AR01", "AZ03", "AZ05", "AZ08", "CA01", "CA05", "CA11", "CA16", "CA18", "CA21")

我想将字符串在第二个字符之后拆分,并将它们放入两列中。

这样数据看起来像这样:

state  district
AR        01
AZ        03
AZ        05
AZ        08
CA        01
CA        05
CA        11
CA        16
CA        18
CA        21

有没有一个简单的代码可以完成这个任务?非常感谢您的帮助。


1
你看过 substr 吗? - Mike
我不熟悉这个。我更熟悉strsplit()函数。但是由于没有可分割的内容,在这种情况下它并不适用。 - Sharif Amlani
6个回答

8

如果您想始终按第二个字符拆分,则可以使用 substr

District <- c("AR01", "AZ03", "AZ05", "AZ08", "CA01", "CA05", "CA11", "CA16", "CA18", "CA21")
#split district  starting at the first and ending at the second
state <- substr(District,1,2)
#split district starting at the 3rd and ending at the 4th
district <- substr(District,3,4)
#put in data frame if needed.
st_dt <- data.frame(state = state, district = district, stringsAsFactors = FALSE)

1
这非常有帮助!感谢您提供代码和注释。 - Sharif Amlani

5

您可以使用R基础库中的strcapture函数:

 strcapture("(\\w{2})(\\w{2})",District,
                    data.frame(state = character(),District = character()))
   state District
1     AR       01
2     AZ       03
3     AZ       05
4     AZ       08
5     CA       01
6     CA       05
7     CA       11
8     CA       16
9     CA       18
10    CA       21

\\w{2} 意味着两个单词


3

楼主已经写道

我更熟悉strsplit(),但由于没有什么可以拆分的,所以在这种情况下不适用

相反! 有东西可以拆分,它叫做回顾后发:

strsplit(District, "(?<=[A-Z]{2})", perl = TRUE) 

回顾正则表达式中的“后行断言”(lookbehind)功能,它会在两个大写字母之间插入一个不可见的间隔,并在此处将字符串分割。

最终结果是一个向量列表。

[[1]]
[1] "AR" "01"

[[2]]
[1] "AZ" "03"

[[3]]
[1] "AZ" "05"

[[4]]
[1] "AZ" "08"

[[5]]
[1] "CA" "01"

[[6]]
[1] "CA" "05"

[[7]]
[1] "CA" "11"

[[8]]
[1] "CA" "16"

[[9]]
[1] "CA" "18"

[[10]]
[1] "CA" "21"

可以被转化为矩阵,例如通过

do.call(rbind, strsplit(District, "(?<=[A-Z]{2})", perl = TRUE))
      [,1] [,2]
 [1,] "AR" "01"
 [2,] "AZ" "03"
 [3,] "AZ" "05"
 [4,] "AZ" "08"
 [5,] "CA" "01"
 [6,] "CA" "05"
 [7,] "CA" "11"
 [8,] "CA" "16"
 [9,] "CA" "18"
[10,] "CA" "21"

1
感谢您提供这个。这使得使用data.table中的tstrsplit高效地拆分大型字符串表成为可能。 - FXQuantTrader

1

使用tidyr中的函数separate,借助于tidyverse,这个过程非常简单:

library(tidyverse)
District %>% 
  as.tibble() %>% 
  separate(value, c("state", "district"), sep = "(?<=[A-Z]{2})")

# A tibble: 10 × 2
   state district
   <chr> <chr>   
 1 AR    01      
 2 AZ    03      
 3 AZ    05      
 4 AZ    08      
 5 CA    01      
 6 CA    05      
 7 CA    11      
 8 CA    16      
 9 CA    18      
10 CA    21      

1
我们可以使用 str_match 来分别捕获前两个字符和剩余字符串并放入不同的列中。
stringr::str_match(District, "(..)(.*)")[, -1]

#      [,1] [,2]
# [1,] "AR" "01"
# [2,] "AZ" "03"
# [3,] "AZ" "05"
# [4,] "AZ" "08"
# [5,] "CA" "01"
# [6,] "CA" "05"
# [7,] "CA" "11"
# [8,] "CA" "16"
# [9,] "CA" "18"
#[10,] "CA" "21"

0

将其视为固定宽度文件,并导入:

# read fixed width file
read.fwf(textConnection(District), widths = c(2, 2), colClasses = "character")
#    V1 V2
# 1  AR 01
# 2  AZ 03
# 3  AZ 05
# 4  AZ 08
# 5  CA 01
# 6  CA 05
# 7  CA 11
# 8  CA 16
# 9  CA 18
# 10 CA 21

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接