括号内的gsub和pad

时间:2012-10-13 20:44:23

标签: r

我有这样的矢量:

x <- c("20(0.23)", "15(0.2)", "16(0.09)")

我不想弄乱括号外面的数字,但想要删除内部数字的前导零,并使所有内容都有2位数。输出结果如下:

"20(.23)", "15(.20)", "16(.09)"

有用的信息:

我可以使用以下函数删除前导零并保留2位数:LINK

numformat <- function(val) { sub("^(-?)0.", "\\1.", sprintf("%.2f", val)) }

numformat(c(0.2, 0.26))
#[1] ".20" ".26"

我知道gsub可以使用,但我不知道如何。我会提供一个strsplit答案,但这充其量只是hackish。

4 个答案:

答案 0 :(得分:6)

gsubfn包允许您使用应用于匹配的函数替换正则表达式匹配的任何内容。因此,我们可以使用numformat函数

中的内容
library(gsubfn)
# Note that I added as.numeric in because what will be passed in
# is a character string
numformat <- function(val){sub("^(-?)0.", "\\1.", sprintf("%.2f", as.numeric(val)))}
gsubfn("0\\.\\d+", numformat, x)
#[1] "20(.23)" "15(.20)" "16(.09)"

答案 1 :(得分:3)

pad.fix<-function(x){
y<-gsub('\\.(\\d)\\)','\\.\\10\\)',x)
gsub('0\\.','\\.',y)
}

如果需要,第一个gsub会添加一个尾随零,第二个gsub会删除前导零。

答案 2 :(得分:2)

这是泰勒问题中的另一个,为了复杂起见,这些问题似乎很复杂:)

所以你走了:

R> x <- c("20(0.23)", "15(0.2)", "16(0.09)")
R> sapply(strsplit(gsub("^(\\d+)\\((.*)\\)$", "\\1 \\2", x), " "), 
+         function(x) sprintf("%2d(.%02d)", 
+                              as.numeric(x[1]), 
+                              as.numeric(x[2])*100))
[1] "20(.23)" "15(.20)" "16(.09)"
R> 

我们在这里做了几件事:

  1. gsub()选出两个数字:首先是parens之前的数字,然后是parens中的数字之一。 [事后看来,应该在小数点后选择,见下文。]
  2. 这只是用空白打印出来,例如:第一个"20 0.23"
  3. 然后我们在此使用标准strsplit()
  4. 然后,我们使用sapply来处理从strsplit
  5. 获得的列表
  6. 我们将第一个数字打印成两位数字。
  7. 第二个更棘手 - (s)printf()系列无法抑制前导零,因此我们打印小数,打印整数的两位数 - 并转换第二个相应的数字。
  8. 这一切都很简洁,但却更清晰。

    编辑:我不经常提供最快的解决方案,但是当我这样做时,至少我可以幸灾乐祸:

    R> dason <- function(x) { numformat <- function(val){sub("^(-?)0.", "\\1.", sprintf("%.2f", as.numeric(val)))}; gsubfn("0\\.\\d+", numformat, x) }
    R> dirk <- function(x) { sapply(strsplit(gsub("^(\\d+)\\((.*)\\)$", "\\1 \\2", x), " "), function(x) sprintf("%2d(.%02d)", as.numeric(x[1]), as.numeric(x[2])*100)) }
    R> 
    R> dason(x)
    [1] "20(.23)" "15(.20)" "16(.09)"
    R> dirk(x)
    [1] "20(.23)" "15(.20)" "16(.09)"
    R> 
    R> res <- benchmark(dason(x), dirk(x), replications=1000, order="relative")
    R> res
          test replications elapsed relative user.self sys.self user.child sys.child
    2  dirk(x)         1000   0.133    1.000     0.132    0.000          0         0
    1 dason(x)         1000   2.026   15.233     1.960    0.064          0         0
    R> 
    

    所以大约15个rimes更快。在这个上下文中并不重要,但从长远来看,速度永远不会伤害任何人。

答案 3 :(得分:0)

gsub回答这个问题至多是丑陋的。

x <- c("20(0.23)", "15(0.2)", "16(0.09)")

numformat <- function(val) { sub("^(-?)0.", "\\1.", sprintf("%.2f", val)) }
z <- do.call(rbind, strsplit(gsub("\\)", "", x), "\\("))
z[, 2] <- numformat(as.numeric(z[, 2]))
paste0(z[, 1], "(", z[, 2], ")")