R中字母数字范围内的所有字符串

R中字母数字范围内的所有字符串,r,regex,string,R,Regex,String,在R中,给定字符串的“范围”,如何获得字符串向量?(相当于x:y,但允许x和y是相同长度的字符串)几个示例 “A001”:“A003”==c(“A001”、“A002”、“A003”) “A99”:“B02”==c(“A99”、“B00”、“B01”、“B02”) 更新: 我可以使用 粘贴0('A',sprintf('02d',1:10)) [1] “A01”“A02”“A03”“A04”“A05”“A06”“A07”“A08”“A09”“A10” 但我不知道如何以无缝的方式从A到B(即A9

在R中,给定字符串的“范围”,如何获得字符串向量?(相当于x:y,但允许x和y是相同长度的字符串)几个示例

“A001”:“A003”==c(“A001”、“A002”、“A003”)
“A99”:“B02”==c(“A99”、“B00”、“B01”、“B02”)
更新: 我可以使用

粘贴0('A',sprintf('02d',1:10)) [1] “A01”“A02”“A03”“A04”“A05”“A06”“A07”“A08”“A09”“A10”
但我不知道如何以无缝的方式从A到B(即A99:B02)。

是的!这里有一个对你有用的例子。生成矩阵的
outer
函数,但您始终可以使用嵌套的
list
unlist
包装器进行修复

您可以使用单个
nums
赋值来完成此操作,除非您指定需要两位代码,因此额外的
paste0
为1:10

请注意,这不适用于从“A99”到“B02”的“概括”情况,但生成更大的列表并将其子集可能会更容易

letts <- c("a", "b", "c")
nums <- c(paste0("0", c(0:9)), 10:99)
sort(unlist(list(outer(letts, nums, paste0))))

lettspunitended的回答启发我想出一个有效的解决方案(包括“概括”案例,即从“A99”到“B02”)

你可以做:

str_seq=function(X){
    a = toupper(strsplit(X, ':')[[1]])# split while ensuring the letters are uppercase
    nums = as.numeric(sub('[A-Z]', '', a))# Obtain the numbers
    stopifnot(nums < 100) # If the number for a range is greater than 100 produce an error
    a = as.numeric(paste0(setNames(1:26, LETTERS)[sub('\\d+', '', a)],sprintf("%02d", nums)))
    b = do.call(seq, as.list(c(a, by = if (diff(a) > 0) 1 else -1))) # Ensure you can go forward or backward
    b = b[!!b%%100] # Remove A00,B00, etc
    paste0(LETTERS[b %/% 100], sprintf("%02d", b %% 100))
 }

str_seq('i89:j23')
 [1] "I89" "I90" "I91" "I92" "I93" "I94" "I95" "I96" "I97" "I98" "I99" "J01" "J02" "J03" "J04"
[16] "J05" "J06" "J07" "J08" "J09" "J10" "J11" "J12" "J13" "J14" "J15" "J16" "J17" "J18" "J19"
[31] "J20" "J21" "J22" "J23"
> str_seq('j23:i89')
 [1] "J23" "J22" "J21" "J20" "J19" "J18" "J17" "J16" "J15" "J14" "J13" "J12" "J11" "J10" "J09"
[16] "J08" "J07" "J06" "J05" "J04" "J03" "J02" "J01" "I99" "I98" "I97" "I96" "I95" "I94" "I93"
[31] "I92" "I91" "I90" "I89"
str_seq=函数(X){
a=toupper(strsplit(X,,:')[[1]])#在确保字母大写的同时进行拆分
nums=as.numeric(sub('[A-Z]','',A))#获取数字
stopifnot(nums<100)#如果某个范围的数字大于100,则会产生错误
a=as.numeric(粘贴0(设置名称(1:26,字母)[sub('\\d+','',a)],sprintf(“%02d”,nums)))
b=do.call(seq,as.list(c(a,by=if(diff(a)>0)1 else-1))#确保可以前进或后退
b=b[!!b%%100]#移除A00、B00等
粘贴0(字母[b%/%100],sprintf(“%02d”,b%%100))
}
str_seq('i89:j23')
[1] “I89”“I90”“I91”“I92”“I93”“I94”“I95”“I96”“I97”“I98”“I99”“J01”“J02”“J03”“J04”
[16] “J05”“J06”“J07”“J08”“J09”“J10”“J11”“J12”“J13”“J14”“J15”“J16”“J17”“J18”“J19”
[31]“J20”“J21”“J22”“J23”
>str_seq('j23:i89')
[1] “J23”“J22”“J21”“J20”“J19”“J18”“J17”“J16”“J15”“J14”“J13”“J12”“J11”“J10”“J09”
[16] “J08”“J07”“J06”“J05”“J04”“J03”“J02”“J01”“I99”“I98”“I97”“I96”“I95”“I94”“I93”
[31]“I92”“I91”“I90”“I89”

您对每个范围都有限制吗在我的特定示例中,第一个数字总是字母(a-Z),后面的数字总是数字(0-9)。而且字符串的长度不会改变。如果字符串的长度为3,则完整的可能范围为A00:Z99(需要在上面进行编辑)。A09之后将是A10。。。A99之后将是B00
str_seq=function(X){
    a = toupper(strsplit(X, ':')[[1]])# split while ensuring the letters are uppercase
    nums = as.numeric(sub('[A-Z]', '', a))# Obtain the numbers
    stopifnot(nums < 100) # If the number for a range is greater than 100 produce an error
    a = as.numeric(paste0(setNames(1:26, LETTERS)[sub('\\d+', '', a)],sprintf("%02d", nums)))
    b = do.call(seq, as.list(c(a, by = if (diff(a) > 0) 1 else -1))) # Ensure you can go forward or backward
    b = b[!!b%%100] # Remove A00,B00, etc
    paste0(LETTERS[b %/% 100], sprintf("%02d", b %% 100))
 }

str_seq('i89:j23')
 [1] "I89" "I90" "I91" "I92" "I93" "I94" "I95" "I96" "I97" "I98" "I99" "J01" "J02" "J03" "J04"
[16] "J05" "J06" "J07" "J08" "J09" "J10" "J11" "J12" "J13" "J14" "J15" "J16" "J17" "J18" "J19"
[31] "J20" "J21" "J22" "J23"
> str_seq('j23:i89')
 [1] "J23" "J22" "J21" "J20" "J19" "J18" "J17" "J16" "J15" "J14" "J13" "J12" "J11" "J10" "J09"
[16] "J08" "J07" "J06" "J05" "J04" "J03" "J02" "J01" "I99" "I98" "I97" "I96" "I95" "I94" "I93"
[31] "I92" "I91" "I90" "I89"