根据特定值创建新变量

Create new variables based upon specific values

我阅读了正则表达式和 Hadley Wickham 的 stringrdplyr 包,但不知道如何让它工作。

我在一个数据框中有图书馆流通数据,以索书号为字符变量。我想使用首字母大写并将其设为新变量,并将字母和句点之间的数字设为第二个新变量。

Call_Num
HV5822.H4 C47 Circulating Collection, 3rd Floor
QE511.4 .G53 1982 Circulating Collection, 3rd Floor
TL515 .M63 Circulating Collection, 3rd Floor
D753 .F4 Circulating Collection, 3rd Floor
DB89.F7 D4 Circulating Collection, 3rd Floor 

怎么样

rl <- read.table(header = TRUE, text = "Call_Num
'HV5822.H4 C47 Circulating Collection, 3rd Floor'
                 'QE511.4 .G53 1982 Circulating Collection, 3rd Floor'
                 'TL515 .M63 Circulating Collection, 3rd Floor'
                 'D753 .F4 Circulating Collection, 3rd Floor'
                 'DB89.F7 D4 Circulating Collection, 3rd Floor'",
                 stringsAsFactors = FALSE)
cbind(rl, read.table(text = gsub('([A-Z]+)([0-9]+).*', '\1 \2', rl$Call_Num)))

#                                              Call_Num V1   V2
# 1     HV5822.H4 C47 Circulating Collection, 3rd Floor HV 5822
# 2 QE511.4 .G53 1982 Circulating Collection, 3rd Floor QE  511
# 3        TL515 .M63 Circulating Collection, 3rd Floor TL  515
# 4          D753 .F4 Circulating Collection, 3rd Floor  D  753
# 5        DB89.F7 D4 Circulating Collection, 3rd Floor DB   89

如果您想使用 stringr,解决方案可能如下所示:

df <- data.frame(Call_Num = c("HV5822.H4 C47 Circulating Collection, 3rd Floor", "QE511.4 .G53 1982 Circulating Collection, 3rd Floor", "TL515 .M63 Circulating Collection, 3rd Floor", "D753 .F4 Circulating Collection, 3rd Floor", "DB89.F7 D4 Circulating Collection, 3rd Floor"))

require(stringr)

matches = str_match(df$Call_Num, "([A-Z]+)(\d+)\s*\.")
df2 <- data.frame(df, letter=matches[,2], number=matches[,3])
df2
##                                                  Call_Num letter number
## 1     HV5822.H4 C47 Circulating Collection, 3rd Floor     HV   5822
## 2 QE511.4 .G53 1982 Circulating Collection, 3rd Floor     QE    511
## 3        TL515 .M63 Circulating Collection, 3rd Floor     TL    515
## 4          D753 .F4 Circulating Collection, 3rd Floor      D    753
## 5        DB89.F7 D4 Circulating Collection, 3rd Floor     DB     89

我认为将 str_match() 调用粘贴到 dplyrmutate() 中是不值得的,所以我就此打住。或者使用

使用 stringi 包,这将是一种选择。由于您的目标位于字符串的开头,因此 stri_extract_first() 会很好用。 [:alpha:]{1,}表示包含多个字母的字母序列。使用 stri_extract_first(),您可以识别第一个字母序列。同样,您可以使用 stri_extract_first(x, regex = "\d{1,}").

找到第一个数字序列
x <- c("HV5822.H4 C47 Circulating Collection, 3rd Floor",
       "QE511.4 .G53 1982 Circulating Collection, 3rd Floor",
       "TL515 .M63 Circulating Collection, 3rd Floor",
       "D753 .F4 Circulating Collection, 3rd Floor",
       "DB89.F7 D4 Circulating Collection, 3rd Floor")

library(stringi)

data.frame(alpha = stri_extract_first(x, regex = "[:alpha:]{1,}"), 
           number = stri_extract_first(x, regex = "\d{1,}"))

#  alpha number
#1    HV   5822
#2    QE    511
#3    TL    515
#4     D    753
#5    DB     89

您可以使用 gsubfn 包中的 strapply

library(gsubfn)

m <- strapply(as.character(df$Call_Num), '^([A-Z]+)(\d+)', 
     ~ c(id = x, num = y), simplify = rbind)

X <- as.data.frame(m, stringsAsFactors = FALSE)

#   id  num
# 1 HV 5822
# 2 QE  511
# 3 TL  515
# 4  D  753
# 5 DB   89