对 R/Sweave 进行编程以获得正确的 \Sexpr 输出

发布于 2024-08-26 04:06:26 字数 1087 浏览 12 评论 0原文

我在为 Sweave 进行 R 编程时遇到了一些问题,#rstats twitter 小组经常指出这里,所以我想我应该把这个问题向大家提出。我是一名分析师,而不是程序员,所以在我的第一篇文章中请放轻松。

问题是:我正在使用 R 在 Sweave 中起草一份调查报告,并希望使用 \Sexpr{} 报告边际回报。例如,而不是说:

只有 14% 的受访者选择“X”。

我想这样写报告:

只有 \Sexpr{p.mean(variable)}$\%$ 的受访者说“X”。

问题在于,Sweave 将 \Sexpr{} 中的表达式的结果转换为字符串,这意味着 R 中的表达式的输出和我的文档中出现的输出是不同的。例如,上面我使用函数“p.mean”:

p.mean<- 函数 (x) {选项(数字=1)  
mmm<-weighted.mean(x,权重=权重,na.rm=T)  
打印(100*mm)  
}

在 R 中,输出如下所示:

p.mean(变量)
>14

但是当我使用 \Sexpr{p.mean(variable)} 时,我在文档中得到一个未舍入的字符串(在本例中:13.5857142857143)。我尝试在全局环境、函数本身以及各种命令中将函数的输出限制为 digits=1。它似乎只包含 R 打印的内容,而不包含作为表达式结果并最终在 LaTeX 文件中打印的字符转换。

as.character(p.mean(变量))  
>[1]14  
>[1]“13.5857142857143”  

有谁知道我可以通过重新编程 R 函数或使用 Sweave 或 \Sexpr{} 中的设置来限制 LaTeX 文件中打印的数字?

I'm having a bit of a problem programming R for Sweave, and the #rstats twitter group often points here, so I thought I'd put this question to the SO crowd. I'm an analyst- not a programmer- so go easy on my first post.

Here's the problem: I am drafting a survey report in Sweave with R and would like to report the marginal returns in line using \Sexpr{}. For example, rather than saying:

Only 14% of respondents said 'X'.

I want to write the report like this:

Only \Sexpr{p.mean(variable)}$\%$ of respondents said 'X'.

The problem is that Sweave converts the results of the expression in \Sexpr{} to a character string, which means that the output from the expression in R and the output that appears in my document are different. For example, above I use the function 'p.mean':

p.mean<- function (x) {options(digits=1)  
mmm<-weighted.mean(x, weight=weight, na.rm=T)  
print(100*mmm)  
}

In R, the output looks like this:

p.mean(variable)
>14

but when I use \Sexpr{p.mean(variable)}, I get an unrounded character string (in this case: 13.5857142857143) in my document. I have tried to limit the output of my function to digits=1 in the global environment, in the function itself, and and in various commands. It only seems to contain what R prints, not the character transformation that is the result of the expression and which eventually prints in the LaTeX file.

as.character(p.mean(variable))  
>[1] 14  
>[1] "13.5857142857143"  

Does anyone know what I can do to limit the digits printed in the LaTeX file, either by reprogramming the R function or with a setting in Sweave or \Sexpr{}?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

猫腻 2024-09-02 04:06:26

@KennyTM 明白了。 @David,您应该避免使用 options(digits = 1) 因为它会影响您的所有计算(之后它将抑制每个输出中的小数)。因此,在应用 weighted.mean() 后使用 round() 函数。像这样的事情:

\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().. . 你已经拥有了所有的部分,现在只需将它们放在一起即可。

PS

我不确定你的功能是如何工作的......我在分析中从未使用过加权平均值。最让我困惑的是weight=weight。在函数中多放一个参数不是更好吗?坦率地说,我仍然对您的函数给出正确的结果感到惊讶......可能是因为您在函数定义之前定义了 weight 变量。 [编辑]如果您没有预定义权重函数,则您将无法获得函数的加权平均值,而是“常规”平均值!

我希望这个对你有帮助!

亲切的问候,
亚历山大

@KennyTM got it. @David, you should avoid options(digits = 1) since it will affect all of your calculations (it will suppress decimals in each output afterwards). So use round() function after applying the weighted.mean(). Something like this:

\Sexpr{round(p.mean(x))}

And do not use print(), but return(). Here's why:

> 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

Use return() or just type the resulting variable in the last line:

> bar <- function(x) {
   res <- mean(x) + 5
   return(res)
}
> bar(x) + 10
[1] 15

So, rewrite your function, and be sure to use as.character()... you have all the bits, now just put it all together.

P.S.

I'm not sure how you function works... I've never used weighed mean in my analysis. The bit that's puzzling me the most is weight=weight. Wouldn't it be nicer to put one more argument in function? Frankly, I'm still amazed by the fact that your function is giving you right result... probably because you have weight variable defined prior to function definition. [EDIT] You will not get the weighted mean with your function if you don't have weight function predefined, but "regular" mean!

I hope this one helped you!

Kind regards,
Aleksandar

少钕鈤記 2024-09-02 04:06:26

尝试“format”:

options(digits=1)

然后:

\Sexpr{format(p.mean(variable))}

您还可以使用“nsmall”参数:

options(digits=3)
...
\Sexpr{format(sqrt(2)-0.41,nsmall=2)}

如果您熟悉 C,您也可以尝试“sprintf”。

Try 'format':

options(digits=1)

and then:

\Sexpr{format(p.mean(variable))}

You can also use the 'nsmall' argument:

options(digits=3)
...
\Sexpr{format(sqrt(2)-0.41,nsmall=2)}

And you can also try 'sprintf' if you're familiar with C.

嘴硬脾气大 2024-09-02 04:06:26
as.character(round(p.mean(variable)))

as.character(round(p.mean(variable)))

?

酒中人 2024-09-02 04:06:26

sprintf() 函数非常适合格式化数字输出。

the sprintf() function is great for formatting numerical output.

染年凉城似染瑾 2024-09-02 04:06:26

siunitx 包也可用于在 sweave 中设置数字格式。

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}

在此处输入图像描述

knit 代码

默认情况下 knit ,当设置选项 options(digits = 2) 时,\Sexpr 中的数字将四舍五入。但是,如果您希望在不同的地方进行不同的舍入,则以下代码可以工作,它需要进行调整,因为不需要在 knit 中的 \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))
  }
}

The siunitx package can also be used to format numbers in sweave.

Code for Sweave

The following script shows how to use it to format numbers, the syntax is for Sweave. In the preamble you can set your default formatting like

\sisetup{
round-mode = figures,
round-precision = 3
}

and then override it in commands \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}

enter image description here

Code for knitr

In knitr by default, the numbers in \Sexpr are rounded when the option options(digits = 2)is set. But if you want different rounding in different places the following code works, it needs to be adapted as there is no need to double escape antislashes in \Sexpr in knitr.

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))
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文