2

\phantom{...}フォーマットされた数値の文字列の先頭のスペースをコマンドに置き換えたいと思います。ここ...で、は先頭のスペースと同じ長さです。私にできることは次のとおりです。

x <- c(1, 1., 0.230, 10.1, 1000, 10000.12)
y <- format(round(x, 2), nsmall=2, big.mark="\\\\,", big.interval=3L)
gsub(" ", "\\\\phantom{ }", y)

しかし、私はむしろ\phantom{}適切な長さの1つ(その\phantom{ }場合はいくつかなど)が必要\phantom{ }です。

アップデート

Arunのソリューションに基づいて、RLaTeXテーブルに配置されるように数値をフォーマットするためのこの関数を作成しました。

tabAlign <- function(x, nsmall=0L, digits=NULL,
                     flag.before="\\\\phantom{", flag.after="}", embrace="$",
                     big.mark="\\\\,", big.interval=3L, ...)
{
    x <- if(!is.null(digits)) round(x, digits=digits) else x
    x <- format(x, nsmall=nsmall, big.mark=big.mark, big.interval=big.interval, ...)
    x <- sub("^([ ]+)", paste0(flag.before, "\\1", flag.after), x) 
    paste0(embrace, x, embrace) 
}

それでは、それを使って何か便利なことをしましょう。tabAlign(x)与える:

[1] "$\\phantom{       }1.00$" "$\\phantom{       }1.00$"
[3] "$\\phantom{       }0.23$" "$\\phantom{      }10.10$"
[5] "$\\phantom{ }1\\,000.00$" "$10\\,000.12$"           

これをコピーしてLaTeXファイルに貼り付けると、配置が正しくないことがわかります。理由はbig.markです。これにより、(文字列nchar(big.mark)=3内の)スペースが予約されます。Rただし、LaTeXでは、これが占めるスペースがはるかに少ないため、数値が完全に整列しなくなりました。したがって、理想的には、sub()コマンドはnchar(big.mark)(任意のbig.mark)を考慮に入れる必要があります。

更新2

これは、DWinからのヒントを考慮に入れた別の更新です。

tabAlign <- function(x, nsmall=0L, digits=NULL,
                     flag="\\\\phantom{\\1}", embrace="$",
                     big.mark="\\\\,", big.interval=3L, ...)
{
    ## round (if digits is not NULL)
    x <- if(!is.null(digits)) round(x, digits=digits) else x
    ## determine those with/without big.mark (idea from prettyNum())
    y <- format(x, nsmall=nsmall, trim=TRUE)
    y.sp <- strsplit(y, ".", fixed=TRUE)
    B <- sapply(y.sp, `[`, 1L)
    ind.w.big.mark <- grep(paste0("[0-9]{", big.interval+1L, ",}"), B)
    ind.wo.big.mark <- setdiff(1:length(y), ind.w.big.mark)
    ## format the numbers
    x <- format(x, nsmall=nsmall, big.mark=big.mark, big.interval=big.interval, ...)
    ## substitute spaces
    z <- character(l <- length(x))
    n <- nchar(big.mark)
    for(i in seq_len(l)){
        z[i] <- if(i %in% ind.wo.big.mark) sub("^([ ]+)", paste0(flag, big.mark), x[i])
                else sub("^([ ]+)", flag, x[i])
    }
    ## embrace
    paste0(embrace, z, embrace)
}

唯一欠けているのは\phantomif()パーツ内のすべてのスペースではなく、スペースの数だけを置き換えることです- n、ここで、n <- nchar(big.mark)。これはどのように指定できますsub()か?

更新3

これが解決策です(ただし、あまりエレガントではありません...以下を参照してください):

tabAlign <- function(x, nsmall=0L, digits=NULL,
                     flag="\\\\phantom{\\1}", embrace="$",
                     big.mark="\\\\,", big.mark2="\\,", big.interval=3L, ...)
{
    ## round (if digits is not NULL)
    x <- if(!is.null(digits)) round(x, digits=digits) else x
    ## determine those with/without big.mark (idea from prettyNum())
    y <- format(x, trim=TRUE)
    y.sp <- strsplit(y, ".", fixed=TRUE)
    B <- sapply(y.sp, `[`, 1L)
    w.big.mark <- grep(paste0("[0-9]{", big.interval+1L, ",}"), B)
    wo.big.mark <- setdiff(1:length(y), w.big.mark)
    ## format the numbers
    x. <- if(length(wo.big.mark) > 0 && length(w.big.mark) > 0) {
        ## format but trim
        y <- format(x, trim=TRUE, nsmall=nsmall, big.mark=big.mark, big.interval=big.interval, ...)
        ## paste big.mark to all numbers without big.mark
        y[wo.big.mark] <- paste0(big.mark2, y[wo.big.mark])
        format(y, justify="right")
    } else { # either all numbers have big.mark or not
        format(x, nsmall=nsmall, big.mark=big.mark, big.interval=big.interval, ...)
    }
    z <- sub("^([ ]+)", flag, x.)
    ## embrace
    paste0(embrace, z, embrace)
}

x <- c(1, 1., 0.230, 10.1, 1000, 10000.12)
tabAlign(x)
tabAlign(x[1:4])
tabAlign(x[5:6])

指定することしかできないbig.mark(そして指定できないbig.mark2)とよいでしょう。

4

1 に答える 1

3

これで問題は解決しますか?目的の出力を表示すると便利です(式のテスト中に出力を確認するため)。DWinの提案に感謝します(コメントを参照)。

sub("^([ ]+)", "\\\\phantom{\\1}", y)

()は一致するパターン(文字列の先頭から始まる連続したスペースの束)をキャプチャし、このキャプチャされたグループは。で挿入できます\\1。複数の括弧がある場合は、キャプチャされた各グループを\1から\9までの逆参照で挿入できます。

于 2012-12-28T23:29:01.513 に答える