我有这样的矢量:
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。
答案 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>
我们在这里做了几件事:
gsub()
选出两个数字:首先是parens之前的数字,然后是parens中的数字之一。 [事后看来,应该在小数点后选择,见下文。] "20 0.23"
。strsplit()
。sapply
来处理从strsplit
(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个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], ")")