\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のソリューションに基づいて、R
LaTeXテーブルに配置されるように数値をフォーマットするためのこの関数を作成しました。
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)
}
唯一欠けているのは\phantom
、if()
パーツ内のすべてのスペースではなく、スペースの数だけを置き換えることです- 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
)とよいでしょう。