我是R的新手,所以我希望你能帮助我。
我想使用gsub删除除句点和减号之外的所有标点符号,这样我就可以在数据中保留小数点和负数符号。
示例
我的数据框z包含以下数据:
[,1] [,2]
[1,] "1" "6"
[2,] "2@" "7.235"
[3,] "3" "8"
[4,] "4" "$9"
[5,] "£5" "-10"
我想使用gsub("[[:punct:]]", "", z)
删除标点符号。
当前输出
> gsub("[[:punct:]]", "", z)
[,1] [,2]
[1,] "1" "6"
[2,] "2" "7235"
[3,] "3" "8"
[4,] "4" "9"
[5,] "5" "10"
但是,我希望保留“ - ”符号和“。”登录。
所需的输出
PSEUDO CODE:
> gsub("[[:punct:]]", "", z, except(".", "-") )
[,1] [,2]
[1,] "1" "6"
[2,] "2" "7.235"
[3,] "3" "8"
[4,] "4" "9"
[5,] "5" "-10"
我是如何让一些角色免于gsub()函数的?
答案 0 :(得分:11)
你可以放回一些像这样的比赛:
sub("([.-])|[[:punct:]]", "\\1", as.matrix(z))
X..1. X..2.
[1,] "1" "6"
[2,] "2" "7.235"
[3,] "3" "8"
[4,] "4" "9"
[5,] "5" "-10"
我保留.
和-
。
我猜,下一步是将结果强制转换为数字矩阵,所以我在这里结合了两个步骤:
matrix(as.numeric(sub("([.-])|[[:punct:]]", "\\1", as.matrix(z))),ncol=2)
[,1] [,2]
[1,] 1 6.000
[2,] 2 7.235
[3,] 3 8.000
[4,] 4 9.000
[5,] 5 -10.000
答案 1 :(得分:2)
有一些选项可以同时使用基数R (g)sub
和stringr
移除/替换功能来限制R中的通用字符类:
(g)sub
和perl=TRUE
您可以将[[:punct:]]
括号表达式与[:punct:]
POSIX字符类一起使用,并将其限制为(?!\.)
否定前瞻,这将要求右边紧跟的字符不相等。到.
:
(?!\.)[[:punct:]] # Excluding a dot only
(?![.-])[[:punct:]] # Excluding a dot and hyphen
要匹配一个或多个事件,请用一个非捕获组将其包装,然后将+
量词设置为该组:
(?:(?!\.)[[:punct:]])+ # Excluding a dot only
(?:(?![.-])[[:punct:]])+ # Excluding a dot and hyphen
请注意,当您删除找到匹配项时,两个表达式将产生相同的结果,但是,当您需要用其他字符串/字符替换时,量化将允许一次替换样式即可更改整个连续字符块。
使用stringr
替换/删除功能
在进行详细介绍之前,请注意与[[:punct:]]
一起使用的PCRE (g)sub
将与ICU regex library支持的stringr
regex函数中的字符不匹配。您需要改用[\p{P}\p{S}]
,请参见R/regex with stringi/ICU: why is a '+' considered a non-[:punct:] character?
ICU正则表达式库具有一个很好的功能,可以与称为 character class subtraction 的字符类一起使用。
因此,您编写了字符类,例如,所有标点匹配类,例如[\p{P}\p{S}]
,然后想要“排除”(= 减)一个或两个或三个字符,或整个char子类。您可以使用两种表示法:
[\p{P}\p{S}&&[^.]] # Excluding a dot
[\p{P}\p{S}--[.]] # Excluding a dot
[\p{P}\p{S}&&[^.-]] # Excluding a dot and hyphen
[\p{P}\p{S}--[.-]] # Excluding a dot and hyphen
要使用此方法匹配1个以上连续出现的事件,则不需要任何包装组,只需使用+
:
[\p{P}\p{S}&&[^.]]+ # Excluding a dot
[\p{P}\p{S}--[.]]+ # Excluding a dot
[\p{P}\p{S}&&[^.-]]+ # Excluding a dot and hyphen
[\p{P}\p{S}--[.-]]+ # Excluding a dot and hyphen
x <- "Abc.123#&*xxx(x-y-z)???? some@other!chars."
gsub("(?!\\.)[[:punct:]]", "", x, perl=TRUE)
## => [1] "Abc.123xxxxyz someotherchars."
gsub("(?!\\.)[[:punct:]]", "~", x, perl=TRUE)
## => [1] "Abc.123~~~xxx~x~y~z~~~~~ some~other~chars."
gsub("(?:(?!\\.)[[:punct:]])+", "~", x, perl=TRUE)
## => [1] "Abc.123~xxx~x~y~z~ some~other~chars."
library(stringr)
stringr::str_remove_all(x, "[\\p{P}\\p{S}&&[^.]]") # Same as "[\\p{P}\\p{S}--[.]]"
## => [1] "Abc.123xxxxyz someotherchars."
stringr::str_replace_all(x, "[\\p{P}\\p{S}&&[^.]]", "~")
## => [1] "Abc.123~~~xxx~x~y~z~~~~~ some~other~chars."
stringr::str_replace_all(x, "[\\p{P}\\p{S}&&[^.]]+", "~") # Same as "[\\p{P}\\p{S}--[.]]+"
## => [1] "Abc.123~xxx~x~y~z~ some~other~chars."
答案 2 :(得分:1)
另一种思考方式是你想要保留什么?您可以使用正则表达式来保存信息以及省略信息。我有很多数据框需要清理单元并在一次通过中从多行转换,我发现在这些实例中使用apply
系列中的某些东西最容易。
重新创建示例:
a <- c('1', '2@', '3', '4', '£5')
b <- c('6', '7.235', '8', '$9', '-10')
z <- matrix(data = c(a, b), nrow = length(a), ncol=2)
然后将apply
与gsub
结合使用。
apply(z, 2, function(x) as.numeric(gsub('[^0-9\\.\\-]', '', x)))
[,1] [,2]
[1,] 1 6.000
[2,] 2 7.235
[3,] 3 8.000
[4,] 4 9.000
[5,] 5 -10.000
这指示R匹配除数字,句点和连字符/短划线之外的所有内容。就个人而言,我觉得它在这些情况下更清洁,更容易使用,并提供相同的输出。
此外,文档对这些功能强大但令人困惑的正则表达式有很好的解释。
https://stat.ethz.ch/R-manual/R-devel/library/base/html/regex.html
或?regex
答案 3 :(得分:1)
您可以尝试使用此代码。我觉得很方便。
x <- c('6,345', '7.235', '8', '$9', '-10')
gsub("[^[:alnum:]\\-\\.\\s]", "", x)
[1] "6345" "7.235" "8" "9" "-10"
x <- c('1', '2@', '3', '4', '£5')
gsub("[^[:alnum:]\\-\\.\\s]", "", x)
[1] "1" "2" "3" "4" "5"
此代码替换了所有不包含字母数字术语的内容。然后我们添加到例外列表。在这里,我们添加连字符(\-),句号(\。)和空格(\ s)。