2010-03-21 33 views
7

Tengo un problema al programar R para Sweave, y el grupo #rstats twitter a menudo apunta aquí, así que pensé en plantear esta pregunta al público de SO. Soy un analista, no un programador, así que vaya fácil en mi primera publicación.Programando R/Sweave para una salida Sexpr correcta

Aquí está el problema: Estoy redactando un informe de encuesta en Sweave con R y me gustaría informar los retornos marginales en línea usando \Sexpr{}. Por ejemplo, en lugar de decir:

Solo el 14% de los encuestados dijo "X".

quiero escribir el informe de la siguiente manera:

Sólo \ Sexpr {p.mean (variable)} $ \ $% de los encuestados dijo 'X'.

El problema es que Sweave convierte los resultados de la expresión en \Sexpr{} a una cadena de caracteres, lo que significa que la salida de la expresión en R y el resultado que aparece en mi documento son diferentes. Por ejemplo, por encima de utilizo la función 'p.mean':

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

En R, la salida se ve así:

p.mean(variable) 
>14 

pero cuando se utiliza \Sexpr{p.mean(variable)} , Obtengo una cadena de caracteres no redondeada (en este caso: 13.5857142857143) en mi documento. He tratado de limitar la salida de mi función a digits=1 en el entorno global, en la función misma y en varios comandos. Solo parece contener lo que imprime R, no la transformación de caracteres que es el resultado de la expresión y que finalmente se imprime en el archivo LaTeX.

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

¿Alguien sabe qué puedo hacer para limitar los dígitos impresos en el archivo de látex, ya sea mediante la reprogramación de la función R o con un ajuste en Sweave o \Sexpr{}?

Respuesta

4

@KennyTM lo consiguió. @David, debe evitar options(digits = 1) ya que afectará todos sus cálculos (suprimirá decimales en cada salida después). Entonces use la función round() después de aplicar el weighted.mean().Algo como esto:

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

Y Noprint() uso, pero return(). He aquí por qué:

> 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 

Uso return() o simplemente escriba la variable que resulta en la última línea:

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

Así, reescribir su función, y asegúrese de usar as.character() ... tiene todos los bits , ahora solo ponlo todo junto.

P.S.

No estoy seguro de cómo funciona la función ... Nunca he utilizado la media ponderada en mi análisis. Lo que más me desconcierta es weight=weight. ¿No sería mejor poner un argumento más en funcionamiento? Francamente, todavía estoy sorprendido por el hecho de que su función le está dando el resultado correcto ... probablemente porque tiene una variable weight definida antes de la definición de la función. [EDITAR]no obtendrá obtener la media ponderada con su función si no tiene la función weight predefinida, pero significa "regular"!

¡Espero que este te haya ayudado!

Saludos cordiales, Aleksandar

+0

Gracias, Aleksandar.Reescribí la función como esta: p.mean <- function (x) { \t mmm <-weighted.mean (x, peso = peso, na.rm = T) \t retorno (round (100 * mmm)) \t} Especifiqué la variable de ponderación porque estoy intentando minimizar la programación, ya que escribo. Debido a que todos los conjuntos de datos con los que trabajo tienen su variable de peso etiquetada como 'peso', esto hace que mis escritos sean un poco más eficientes. – deoksu

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

?

+0

Gracias! reescribir mi función para: > p.mean <- function (x) { \t mmm <-weighted.mean (x, peso = peso, na.rm = T) \t vuelta (vuelta (100 * mmm)) \t} funciona perfectamente. – deoksu

3

Try 'formato':

options(digits=1) 

y luego:

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

También puede utilizar el 'nsmall' argumento:

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

y también se puede tratar 'sprintf 'si está familiarizado con C.

1

la función sprintf() es grande para el formato de salida numérica.

0

El paquete siunitx también se puede usar para formatear números en sweave.

Código de Sweave

La siguiente secuencia de comandos muestra cómo usarlo para formatear números, la sintaxis es para Sweave. En el preámbulo puede configurar su formato predeterminado como

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

y luego anularlo en los comandos \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

Código de knitr

en knitr por defecto, los números en \ Sexpr se redondean cuando se establece la opción options(digits = 2). Pero si desea un redondeo diferente en diferentes lugares, el siguiente código funciona, debe adaptarse, ya que no es necesario duplicar las antislash en \ Sexpr en 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)) 
    } 
} 
Cuestiones relacionadas