几个月前我asked something similar,但我使用JavaScript来检查提供的字符串是否是“有效”的R对象名称。现在我想通过使用除了R之外的任何东西来实现同样的目标。我想有一个非常好的方法来做这个,有一些整洁的(不那么)深奥的R函数,所以正则表达式在我看来是最后一道防线。有什么想法吗?
哦,是的,使用背蜱和东西被认为是作弊。 =)
答案 0 :(得分:9)
编辑2013-1-9修正正则表达式。以前的正则表达式,从约翰钱伯斯的“数据分析软件”第456页解除,(巧妙地)不完整。 (h.t. Hadley Wickham)
这里有几个问题。可以使用简单的正则表达式来标识所有语法上有效的名称 - 但其中一些名称(如if
和while
)是“保留的”,并且无法分配。
?make.names
解释了语法上有效的名称:
[...]由字母,数字和字母组成 点或下划线字符,以字母或点开头 没有跟着一个数字。诸如“.2way”之类的名称无效[...]
这是相应的正则表达式:
"^([[:alpha:]]|[.][._[:alpha:]])[._[:alnum:]]*$"
要识别非保留名称,您可以利用基函数make.names()
,它从任意字符串构造语法上有效的名称。
isValidAndUnreserved <- function(string) {
make.names(string) == string
}
isValidAndUnreserved(".jjj")
# [1] TRUE
isValidAndUnreserved(" jjj")
# [1] FALSE
全部放在一起
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
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
有关这些问题的更多讨论,请参阅以下评论中由@Hadley链接的the r-devel thread。
答案 1 :(得分:5)
正如Josh所说,make.names
可能是最好的解决方案。它不仅会处理奇怪的标点符号,还会标记保留字:
make.names(".x") # ".x"
make.names("_x") # "X_x"
make.names("if") # " if."
make.names("function") # "function."