使用带有2位有效数字的formatC的好奇输出

时间:2014-12-19 09:53:56

标签: r format significant-digits

我想使用formatC格式化带有2位有效数字的数字。但它有一种奇怪的行为。以下是数据:

(x <- data.frame(  cil = c(1.234, 0.444, 0.712, 0.999, 1.999)
                 , ciu = c(1.812, 1.234, 0.999, 1.199, 2.690)
                 )
 )

x$ci <- with(x,paste("("
              , formatC(cil, format="g", digits=2, flag="#")
              , "-"
              , formatC(ciu, format="g", digits=2, flag="#")
              ,")"
                      )
              )
x

以下是结果:

      cil   ciu         ci
1     1.234 1.812  ( 1.2 - 1.8 )
2     0.444 1.234 ( 0.44 - 1.2 )
3     0.712 0.999 ( 0.71 - 1.0 )
4     0.999 1.199  ( 1.0 - 1.2 )
5     1.999 2.690  (  2. - 2.7 )

在案例5中,我预计 2.0 而不是 2。。对此有解释吗?我对参数的定义有什么问题吗?

2 个答案:

答案 0 :(得分:1)

R 3.1.2上使用linux mint 17,我无法重现问题,因为我得到的确切结果是您的预期输出。但是,如果您有多列(或一般情况下),可以选择使用pastedo.call

1)使用formatC

x$ci <- paste0("(",do.call(`paste`, c(lapply(x[,2:3], function(x) 
 formatC(x, format='g',   digits=2, flag='#')), list(sep=" - "))) ,")")
x$ci
#[1] "(1.2 - 1.8)"  "(0.44 - 1.2)" "(0.71 - 1.0)" "(1.0 - 1.2)"  "(2.0 - 2.7)" 

注意:上面的预期输出完全相同。

2)使用sprintf

我认为另一种选择是使用sprintf如果您需要与更新前显示的@CathG类似的输出

x$ci <- paste0("(",do.call(`paste`, c(lapply(x[2:3], function(x) 
                       sprintf('%0.2f', x)), list(sep="-"))),")")
x$ci
#[1] "(1.23-1.81)" "(0.44-1.23)" "(0.71-1.00)" "(1.00-1.20)" "(2.00-2.69)"

更新

您可以使用regex来解决问题。例如,我创建的5th条目与您的输出相同,并使用正则表达式lookbehind

x$ci[5] <- "( 2. - 2.7 )"
sub('(?<=\\.) ', '0', x$ci, perl=TRUE)
#[1] "( 1.2 - 1.8 )"  "( 0.44 - 1.2 )" "( 0.71 - 1.0 )" "( 1.0 - 1.2 )" 
#[5] "( 2.0- 2.7 )"  

答案 1 :(得分:1)

为了说明我在评论中说的话,你可以这样做:

x$ci<-with(x,paste("(",
                   format(cil,digits=2,nsmall=2),
                   "-",
                   format(ciu,digits=2,nsmall=2),")"))
> x
  case   cil   ciu              ci
1    A 1.234 1.812 ( 1.23 - 1.81 )
2    B 0.444 1.234 ( 0.44 - 1.23 )
3    C 0.712 0.999 ( 0.71 - 1.00 )
4    D 0.999 1.199 ( 1.00 - 1.20 )
5    E 1.999 2.690 ( 2.00 - 2.69 )

或以下,以抑制括号之前或之后的空格:

x$ci<-with(x,paste0("(",
                    format(cil,digits=2,nsmall=2),
                    " - ",
                    format(ciu,digits=2,nsmall=2),")"))
> x
  case   cil   ciu          ci
1    A 1.234 1.812 (1.23 - 1.81)
2    B 0.444 1.234 (0.44 - 1.23)
3    C 0.712 0.999 (0.71 - 1.00)
4    D 0.999 1.199 (1.00 - 1.20)
5    E 1.999 2.690 (2.00 - 2.69)

NB :您实际上可以使用函数formatC获得相同的结果,但使用format="f"代替"g"

更新:

我想0之后2.不打印的事实只是某些R版本中的错误(更奇怪的是:如果你尝试使用2.01代替{{1} }},你会得到1.999 ...)。

要使其适用于您的行并获得您想要的内容,只需添加"2.0"函数:

round