我在为Sweave编程R时遇到了一些问题,#rstats twitter组经常指向这里,所以我想我会把这个问题提到SO人群中。我是一名分析师 - 而不是程序员 - 所以在我的第一篇文章中轻松一点。
问题在于:我正在使用R在Sweave中起草调查报告,并希望使用\Sexpr{}
报告边际收益。例如,而不是说:
只有14%的受访者表示'X'。
我想写这样的报告:
只有\ Sexpr {p.mean(variable)} $ \%$的受访者说'X'。
问题是Sweave将\Sexpr{}
中表达式的结果转换为字符串,这意味着R中表达式的输出和我文档中出现的输出是不同的。例如,上面我使用函数'p.mean':
p.mean<- function (x) {options(digits=1) mmm<-weighted.mean(x, weight=weight, na.rm=T) print(100*mmm) }
在R中,输出如下所示:
p.mean(variable) >14
但是当我使用\Sexpr{p.mean(variable)}
时,我的文档中会得到一个未连接的字符串(在本例中为13.5857142857143)。我试图在全局环境,函数本身和各种命令中将函数的输出限制为digits=1
。它似乎只包含R打印,而不是表达结果的字符转换,最终打印在LaTeX文件中。
as.character(p.mean(variable)) >[1] 14 >[1] "13.5857142857143"
有没有人知道如何通过重新编程R函数或使用Sweave或\Sexpr{}
中的设置来限制LaTeX文件中打印的数字?
答案 0 :(得分:4)
@KennyTM得到了它。 @David,你应该避免options(digits = 1)
,因为它会影响你的所有计算(它会在之后的每个输出中抑制小数)。因此,在应用round()
后使用weighted.mean()
函数。像这样:
\Sexpr{round(p.mean(x))}
并且不使用print()
,但return()
。原因如下:
> set.seed(1234)
> x <- rnorm(100)
> foo <- function(x) {
res <- mean(x) + 5
print(res)
}
> foo(x)
[1] 5
> foo(x) + 10
[1] 5
[1] 15
使用return()
或只在最后一行输入结果变量:
> bar <- function(x) {
res <- mean(x) + 5
return(res)
}
> bar(x) + 10
[1] 15
所以,重写你的功能,并确保使用as.character()
...你拥有所有的位,现在只需将它们放在一起。
P.S。
我不确定你的功能如何...我在分析中从未使用过加权平均值。令我困惑的是weight=weight
。在功能中多放一个参数会不会更好?坦率地说,我仍然对你的函数给你正确的结果感到惊讶...可能是因为你在函数定义之前定义了weight
变量。 [编辑] 如果您没有预定义weight
函数,将不会获取您的函数的加权平均值,但“常规”意味着!
我希望这个帮助过你!
亲切的问候, 亚历山大
答案 1 :(得分:3)
尝试'格式':
options(digits=1)
然后:
\Sexpr{format(p.mean(variable))}
您也可以使用'nsmall'参数:
options(digits=3)
...
\Sexpr{format(sqrt(2)-0.41,nsmall=2)}
如果你熟悉C,你也可以试试'sprintf'。
答案 2 :(得分:2)
as.character(round(p.mean(variable)))
?
答案 3 :(得分:1)
sprintf()函数非常适合格式化数字输出。
答案 4 :(得分:0)
siunitx包也可以用来格式化sweave中的数字。
以下脚本显示了如何使用它来格式化数字,语法适用于 Sweave 。在序言中,您可以设置默认格式,如
\sisetup{
round-mode = figures,
round-precision = 3
}
然后在命令\Sexpr{num(pi,round_precision=2)}
\documentclass[a4paper]{article}
\usepackage{siunitx}
\usepackage{Sweave}
\title{siunitx}
\sisetup{
round-mode = figures,
round-precision = 3
}
\begin{document}
\maketitle
<<sanitize_number,echo=FALSE>>=
num <- function(x,round_precision=NULL)
{
if (is.null(round_precision)) {
return(sprintf("\\\\num{%s}", x))
} else {
return(sprintf("\\\\num[round-precision=%s]{%s}",round_precision, x))
}
}
@
Examples :\\
round\_precision= 2 gives : \Sexpr{num(pi,round_precision=2)} \\
round\_precision= 4 gives : \Sexpr{num(pi,round_precision=4)}\\
Default formatting gives : \Sexpr{num(pi)}
\end{document}
默认情况下,在knitr中,设置选项options(digits = 2)
时,\ Sexpr中的数字将被舍入。但是如果你想在不同的地方进行不同的舍入,下面的代码可以工作,它需要进行调整,因为不需要在编织器中的\ Sexpr中双重逃避反义。
num <- function(x,round_precision=NULL)
{
if (is.null(round_precision)) {
return(sprintf("\\num{%s}", x))
} else {
return(sprintf("\\num[round-precision=%s]{%s}",round_precision, x))
}
}