使用NA拆分字符和数字字符串

时间:2016-01-04 10:42:46

标签: r

对于示例数据框:

df <- structure(list(ID = 1:6, region = structure(c(5L, 3L, 1L, 4L, 
                                                    6L, 2L), .Label = c("AB1", "AB22", "AC225", "AF32", "AX11", "OI222"
                                                    ), class = "factor"), level = c(2L, 3L, 1L, 2L, 3L, 2L)), .Names = c("ID", 
                                                                                                                         "region", "level"), class = "data.frame", row.names = c(NA, -6L
                                                                                                                         ))

我有一个名为region的列,其中至少有两个字符变量,然后是1,2或3个数字变量。级别变量表示该区域的大小(其中级别1表示国家中的最大区域,级别3包含最小区域)。

区域代码不仅详细说明每个ID所指的区域,而且还经常(如果适用)更大的链接区域。

例如,AC225是: 区域0的AC;区域1中的AC2;区域2中的AC22;区域3中的AC225。

我希望使用区域代码为每个ID变量执行此操作。对于某些ID,事情稍微复杂一点,我不会知道区域2或3(然后我希望添加NA)。例如,对于AB32,我希望AB为region.0,AB3为region.1,AB32为region.2,NA为region.3。

我尝试使用stringr函数,但没有取得多大成功:

library(stringr)
df$region.0 <- str_sub(df$region,1,2)
df$region.1 <- str_sub(df$region,1,2,3)
df$region.2 <- str_sub(df$region,1,2,3,4)
df$region.3 <- str_sub(df$region,1,2,3,4,5)

如果有人能帮助我,我将非常感激。

2 个答案:

答案 0 :(得分:3)

也许可以尝试使用stringiregex

library("stringi")

df$region.0 <- stri_extract_all_regex(df$region, "^..")
df$region.1 <- stri_extract_all_regex(df$region, "^...")
df$region.2 <- stri_extract_all_regex(df$region, "^....")
df$region.3 <- stri_extract_all_regex(df$region, "^.....")

> df
  ID region level region.0 region.1 region.2 region.3
1  1   AX11     2       AX      AX1     AX11       NA
2  2  AC225     3       AC      AC2     AC22    AC225
3  3    AB1     1       AB      AB1       NA       NA
4  4   AF32     2       AF      AF3     AF32       NA
5  5  OI222     3       OI      OI2     OI22    OI222
6  6   AB22     2       AB      AB2     AB22       NA

答案 1 :(得分:1)

另一种方式,来自基地R的gsubmapply

数字之前的大写字母数量并不重要,它避免了必须键入的行数与#34; new&#34;要添加的列:

maxlevel <- 3 # you can have more later if you wish to

res <- cbind(df, 
            `colnames<-`(t(mapply(function(x, y){
                                     c(gsub("^([A-Z]+)\\d+$", "\\1", x), 
                                       sapply(1:y, 
                                            function(n){
                                              gsub(paste0("^([A-Z]+\\d{",n,"})\\d*$"), "\\1", x)}), 
                                       rep(NA, maxlevel-y))}, 
                                  df$region, df$level)), 
                          paste("region", 0:maxlevel, sep=".")))
res
#  ID region level region.0 region.1 region.2 region.3
#1  1   AX11     2       AX      AX1     AX11     <NA>
#2  2  AC225     3       AC      AC2     AC22    AC225
#3  3    AB1     1       AB      AB1     <NA>     <NA>
#4  4   AF32     2       AF      AF3     AF32     <NA>
#5  5  OI222     3       OI      OI2     OI22    OI222
#6  6   AB22     2       AB      AB2     AB22     <NA>

<强> 解释

mapply获取区域和级别的名称来计算一个向量,该向量仅包含区域名称的字母,字母以及从1到level的数字最后NA到达等于maxlevel的长度。