Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R中的字符串ID格式检查和填充_R_String_Input - Fatal编程技术网

R中的字符串ID格式检查和填充

R中的字符串ID格式检查和填充,r,string,input,R,String,Input,一些代码的格式为数字除以破折号(例如,社会保险号码的格式通常为“ddd dddd dddd”,其中d代表任何数字;用简短的3-2-4格式表示,代表每个“区块”中的数字数) 我需要输入5-4、4-4或5-3格式的产品代码,然后: (a) 验证它们是否符合这些格式中的任何一种,以及(b)用零填充,以便输出为5-4格式 这里有一个代码可以做到这一点。有更好的方法吗?如何将其矢量化 library(stringr) as_product_code <- function(x) { # Cle

一些代码的格式为数字除以破折号(例如,社会保险号码的格式通常为“ddd dddd dddd”,其中d代表任何数字;用简短的3-2-4格式表示,代表每个“区块”中的数字数)

我需要输入5-4、4-4或5-3格式的产品代码,然后: (a) 验证它们是否符合这些格式中的任何一种,以及(b)用零填充,以便输出为5-4格式

这里有一个代码可以做到这一点。有更好的方法吗?如何将其矢量化

library(stringr)

as_product_code <- function(x) {
  # Clean Product Codes
  #  Input: 5-4, 5-3, or 4-4 product code.
  #  Output: 5-4 product code.

  chunks <- unlist(strsplit(x, split = "-", fixed = T))
  if (length(chunks == 2) & (identical(nchar(chunks), c(5L, 3L)) |
                             identical(nchar(chunks), c(5L, 4L)) |
                             identical(nchar(chunks), c(4L, 4L)))) {
    output_code<- paste(str_pad(chunks[1], pad = "0", width = 5),
                        str_pad(chunks[2], pad = "0", width = 4),
                        sep = "-")
    return(output_code)
  } else {
    warning("Unexpected format. Doing nothing.")
    return(x)
  }
}
库(stringr)

作为产品,您可以使用正则表达式和
stringr
-包。对于不遵循指定模式的条目,这将返回NA

对于正则表达式,请查看

\\d
表示任何数字(0-9),括号{}中的数字表示重复次数(或{min,max}或{exact})。
^
表示我正在查看字符串的开头,
$
标记结束。因此,我不匹配字符串末尾的ab

test <- c("1234-1234", "12345-123", "12345-1234ab", "12345-1234", "1234-123")

ifelse(str_detect(test, "^(\\d{4,5})-(\\d{4})$|^(\\d{5})-(\\d{3})$"), 
       str_replace_all(test, c("^(\\d{4})-" = "0\\1-", "-(\\d{3})$" = "-0\\1")), 
       NA)

[1] "01234-1234" "12345-0123" NA           "12345-1234" NA 

test您可以使用正则表达式和
stringr
-包。对于不遵循指定模式的条目,这将返回NA

对于正则表达式,请查看

\\d
表示任何数字(0-9),括号{}中的数字表示重复次数(或{min,max}或{exact})。
^
表示我正在查看字符串的开头,
$
标记结束。因此,我不匹配字符串末尾的ab

test <- c("1234-1234", "12345-123", "12345-1234ab", "12345-1234", "1234-123")

ifelse(str_detect(test, "^(\\d{4,5})-(\\d{4})$|^(\\d{5})-(\\d{3})$"), 
       str_replace_all(test, c("^(\\d{4})-" = "0\\1-", "-(\\d{3})$" = "-0\\1")), 
       NA)

[1] "01234-1234" "12345-0123" NA           "12345-1234" NA 

test您可以使用
Vectorize
base R函数:

as_product_code <- function(x) {
#your function
}

x <- c('1234-1234','1234-1234')

as_product_code_vec <- Vectorize(as_product_code,'x',USE.NAMES = F)
as_product_code_vec(x)

as\u product\u code您可以使用
矢量化
base R函数:

as_product_code <- function(x) {
#your function
}

x <- c('1234-1234','1234-1234')

as_product_code_vec <- Vectorize(as_product_code,'x',USE.NAMES = F)
as_product_code_vec(x)

as_product_code我们实际上可以利用这里的
dataframe
结构来获得一些矢量化帮助

# Create reproducible example
set.seed(9025)

d1 = sample(1:5, 1e5, replace=TRUE)
d2 = sample(1:5, 1e5, replace=TRUE)
codes = sapply(1:1e5, function(i) {
  c1 = paste0(sample(1:9, d1[i]), collapse='')
  c2 = paste0(sample(1:9, d2[i]), collapse='')
  paste(c1, c2, sep='-')
})

library(stringr)
library(tidyverse)

# Create our dataframe, separate the product code, pad the values,
# and use vectorized ifelse to "remove" bad product codes.
output = codes %>%
  tbl_df() %>%
  separate(value, into=c('c1', 'c2'), sep='-', remove=TRUE) %>%
  mutate(include = ifelse(nchar(c1) %in% 4:5 & 
                          nchar(c2) %in% 3:4 & 
                          (nchar(c1) + nchar(c2) > 7), 
                          1, 0),
         c1 = str_pad(c1, width=5, side='left', pad=0),
         c2 = str_pad(c2, width=4, side='right', pad=0),
         code = paste(c1, c2, sep='-')) %>%
  mutate(code = ifelse(include == 1, code, '')) %>%
  pull(code)

head(codes)

[1] "62971-2"   "5-51864"   "32419-328" "931-8"    
[5] "18324-248" "8-628" 

head(output)

[1] ""           ""           "32419-3280"
[4] ""           "18324-2480" "" 

实际上,我们可以利用这里的
dataframe
结构来获得一些矢量化帮助

# Create reproducible example
set.seed(9025)

d1 = sample(1:5, 1e5, replace=TRUE)
d2 = sample(1:5, 1e5, replace=TRUE)
codes = sapply(1:1e5, function(i) {
  c1 = paste0(sample(1:9, d1[i]), collapse='')
  c2 = paste0(sample(1:9, d2[i]), collapse='')
  paste(c1, c2, sep='-')
})

library(stringr)
library(tidyverse)

# Create our dataframe, separate the product code, pad the values,
# and use vectorized ifelse to "remove" bad product codes.
output = codes %>%
  tbl_df() %>%
  separate(value, into=c('c1', 'c2'), sep='-', remove=TRUE) %>%
  mutate(include = ifelse(nchar(c1) %in% 4:5 & 
                          nchar(c2) %in% 3:4 & 
                          (nchar(c1) + nchar(c2) > 7), 
                          1, 0),
         c1 = str_pad(c1, width=5, side='left', pad=0),
         c2 = str_pad(c2, width=4, side='right', pad=0),
         code = paste(c1, c2, sep='-')) %>%
  mutate(code = ifelse(include == 1, code, '')) %>%
  pull(code)

head(codes)

[1] "62971-2"   "5-51864"   "32419-328" "931-8"    
[5] "18324-248" "8-628" 

head(output)

[1] ""           ""           "32419-3280"
[4] ""           "18324-2480" "" 

在我看来,这已经相当矢量化了!我只需要删除函数@AntoinePissoort中的
库(stringr)
,它不起作用,例如
x=c(“1234-1234”,“1234-1234”)
@AntoinePissoort,我已经编辑以反映您的其他建议。谢天谢地,在我看来,这已经相当矢量化了!我只需要删除函数@AntoinePissoort中的
库(stringr)
,它不起作用,例如
x=c(“1234-1234”,“1234-1234”)
@AntoinePissoort,我已经编辑以反映您的其他建议。感谢伟大的方法。但它通过4-3作为正确的输入。哦,是的,这是真的,我做了一个快速修复。可能有一个更优雅的解决方案来验证输入。在这种情况下,更多可能的组合会变得更混乱,但对于你的问题,它应该起到作用。很好的方法。但它通过4-3作为正确的输入。哦,是的,这是真的,我做了一个快速修复。可能有一个更优雅的解决方案来验证输入。在这种情况下,可能会有更多可能的组合,但对于您的问题,它应该做到这一点。这不会验证输入和PAD错误。例如,“1234-123”变为“01234-1230”。@dzeltzer在验证逻辑方面有点笨拙,但更新的代码包含了您的验证逻辑。@dzeltzer由于某种原因,我今天上午所做的最后更改没有应用到我的编辑中,这将导致不正确的输出。现在的代码应该可以工作了。这不会验证输入,也不会导致错误。例如,“1234-123”变为“01234-1230”。@dzeltzer在验证逻辑方面有点笨拙,但更新的代码包含了您的验证逻辑。@dzeltzer由于某种原因,我今天上午所做的最后更改没有应用到我的编辑中,这将导致不正确的输出。现在的代码应该可以工作。