5

我有这样的向量:

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答案,但这充其量是骇人听闻的。

4

4 回答 4

7

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)"
于 2012-10-13T21:15:15.893 回答
3
pad.fix<-function(x){
y<-gsub('\\.(\\d)\\)','\\.\\10\\)',x)
gsub('0\\.','\\.',y)
}

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

于 2012-10-14T03:53:29.690 回答
2

这是 Tyler 的又一个问题,只是为了复杂化而显得复杂:)

所以你去:

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()挑选两个数字:第一个是括号前的数字,然后是括号内的一个。[事后看来,应该选择小数点后,见下文。]
  2. 这仅使用空格将它们打印出来,例如"20 0.23"第一个。
  3. 然后,我们对此使用标准strsplit()
  4. 然后我们sapply用来处理我们从中得到的列表strsplit
  5. 我们将第一个数字打印为两位整数。
  6. 第二个更棘手 - 该(s)printf()系列无法抑制前导零,因此我们打印小数,并打印整数的两位数 - 并相应地转换第二个数字。

这一切都很简洁,在一条线上,但它会更清楚地分解。

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

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 分钟。在这种情况下,这并不重要,但从长远来看,速度永远不会伤害任何人。

于 2012-10-13T21:46:56.890 回答
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], ")")
于 2012-10-13T20:48:10.773 回答