简体   繁体   English

检查字符值是否是有效的 R 对象名称

[英]Check if character value is a valid R object name

Several months ago I asked something similar , but I was using JavaScript to check if provided string is a "valid" R object name.几个月前我问过类似的问题,但我使用 JavaScript 来检查提供的字符串是否是“有效”的 R 对象名称。 Now I'd like to achieve the same by using nothing but R. I suppose that there's a very nice way to do this, with some neat (not so) esoteric R function, so regular expressions seem to me as the last line of defence.现在我想通过只使用 R 来实现相同的目标。我想有一种非常好的方法可以做到这一点,使用一些简洁(不是那么)深奥的 R 函数,所以正则表达式在我看来是最后一道防线. Any ideas?有任何想法吗?

Oh, yeah, using back-ticks and stuff is considered cheating.哦,是的,使用反引号之类的东西被认为是作弊。 =) =)

Edited 2013-1-9 to fix regular expression.编辑 2013-1-9 以修复正则表达式。 Previous regular expression, lifted from page 456 of John Chambers' "Software for Data Analysis", was (subtly) incomplete.以前的正则表达式取自 John Chambers 的“数据分析软件”第 456 页,是(巧妙地)不完整的。 (ht Hadley Wickham) (哈德利·威克姆)


There are a couple of issues here.这里有几个问题。 A simple regular expression can be used to identify all syntactically valid names --- but some of those names (like if and while ) are 'reserved', and cannot be assigned to.一个简单的正则表达式可用于标识所有语法上有效的名称 --- 但其中一些名称(如ifwhile )是“保留的”,不能分配给。

  • Identifying syntactically valid names:识别语法上有效的名称:

    ?make.names explains that a syntactically valid name: ?make.names解释了语法上有效的名称:

    [...] consists of letters, numbers and the dot or underline characters and starts with a letter or the dot not followed by a number. [...] 由字母、数字和点或下划线字符组成,以字母或点开头,后面不跟数字。 Names such as '".2way"' are not valid [...]诸如 '".2way"' 之类的名称无效 [...]

    Here is the corresponding regular expression:下面是对应的正则表达式:

     "^((([[:alpha:]]|[.][._[:alpha:]])[._[:alnum:]]*)|[.])$"
  • Identifying unreserved syntactically valid names识别无保留的语法有效名称

    To identify unreserved names, you can take advantage of the base function make.names() , which constructs syntactically valid names from arbitrary character strings.要识别未保留的名称,您可以利用基本函数make.names() ,它从任意字符串构造语法上有效的名称。

     isValidAndUnreserved <- function(string) { make.names(string) == string } isValidAndUnreserved(".jjj") # [1] TRUE isValidAndUnreserved(" jjj") # [1] FALSE
  • Putting it all together把这一切放在一起

    isValidName <- function(string) { grepl("^((([[:alpha:]]|[.][._[:alpha:]])[._[:alnum:]]*)|[.])$", string) } isValidAndUnreservedName <- function(string) { make.names(string) == string } testValidity <- function(string) { valid <- isValidName(string) unreserved <- isValidAndUnreservedName(string) reserved <- (valid & ! unreserved) list("Valid"=valid, "Unreserved"=unreserved, "Reserved"=reserved) } testNames <- c("mean", ".j_j", ".", "...", "if", "while", "TRUE", "NULL", "_jj", " j", ".2way") t(sapply(testNames, testValidity))
     Valid Unreserved Reserved mean TRUE TRUE FALSE .j_j TRUE TRUE FALSE . TRUE TRUE FALSE ... TRUE TRUE FALSE if TRUE FALSE TRUE while TRUE FALSE TRUE TRUE TRUE FALSE TRUE NULL TRUE FALSE TRUE _jj FALSE FALSE FALSE j FALSE FALSE FALSE # Note: these tests are for " j", not "j" .2way FALSE FALSE FALSE

For more discussion of these issues, see the r-devel thread linked to by @Hadley in the comments below.有关这些问题的更多讨论,请参阅@Hadley 在下面的评论中链接到的 r-devel 线程

As Josh suggests, make.names is probably the best solution to this.正如 Josh 所建议的, make.names可能是最好的解决方案。 Not only will it handle weird punctuation, it'll also flag reserved words:它不仅会处理奇怪的标点符号,还会标记保留字:

make.names(".x")   # ".x"
make.names("_x")   # "X_x"
make.names("if")   # " if."
make.names("function")  # "function."

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM