2010-03-21 11 views
7

J'ai un peu de mal à programmer R pour Sweave, et le groupe twitter #rstats pointe souvent ici, alors j'ai pensé que je poserais cette question à la foule SO. Je suis un analyste, pas un programmeur, alors allez-y doucement sur mon premier post.Programmation R/Sweave pour une sortie Sexpr correcte

Voici le problème: Je rédige un rapport d'enquête dans Sweave avec R et j'aimerais signaler les retours marginaux en ligne en utilisant \Sexpr{}. Par exemple, plutôt que de dire:

Seulement 14% des répondants ont répondu «X».

Je veux écrire le rapport comme celui-ci:

uniquement \ {SEXPR p.mean (variable)} $ \% $ des répondants ont dit 'X'.

Le problème est que Sweave convertit les résultats de l'expression dans \Sexpr{} à une chaîne de caractères, ce qui signifie que la sortie de l'expression dans la R et la sortie qui apparaît dans mon document sont différents. Par exemple, au-dessus utiliser la fonction 'p.mean':

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

En R, la sortie ressemble à ceci:

p.mean(variable) 
>14 

mais quand j'utilise \Sexpr{p.mean(variable)} , Je reçois une chaîne de caractères non ficelée (dans ce cas: 13.5857142857143) dans mon document. J'ai essayé de limiter la sortie de ma fonction à digits=1 dans l'environnement global, dans la fonction elle-même, et dans diverses commandes. Il semble seulement contenir ce que R imprime, pas la transformation de caractère qui est le résultat de l'expression et qui s'imprime finalement dans le fichier LaTeX.

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

Est-ce que quelqu'un sait ce que je peux faire pour limiter les chiffres imprimés dans le fichier LaTeX, que ce soit en reprogrammant la fonction R ou avec un paramètre dans Sweave ou \Sexpr{}?

Répondre

4

@KennyTM l'a eu. @David, vous devriez éviter options(digits = 1) car cela affectera tous vos calculs (il supprimera ensuite les décimales dans chaque sortie). Donc, utilisez la fonction round() après avoir appliqué weighted.mean().Quelque chose comme ceci:

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

Et ne le font pas usageprint(), mais return(). Voici pourquoi:

> 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 

Utilisez return() ou tapez simplement la variable résultant dans la dernière ligne:

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

Ainsi, réécrire votre fonction, et assurez-vous d'utiliser as.character() ... vous avez tous les bits , maintenant tout mettre ensemble.

P.S. Je ne suis pas sûr comment fonctionne votre fonction ... Je n'ai jamais utilisé la moyenne pondérée dans mon analyse. Le bit qui me intrigue le plus est weight=weight. Ne serait-il pas plus agréable de mettre un argument de plus en fonction? Franchement, je suis toujours étonné par le fait que votre fonction vous donne un bon résultat ... probablement parce que vous avez une variable weight définie avant la définition de la fonction. [EDIT]ne sera pas obtenir la moyenne pondérée avec votre fonction si vous n'avez pas prédéfini la fonction weight, mais "régulière" signifie!

J'espère que celui-ci vous a aidé!

Cordialement, Aleksandar

+0

Merci, Aleksandar.Je réécris la fonction comme ceci: p.mean <- function (x) { \t mmm <-weighted.mean (x, = poids, na.rm = T) \t retour (rond (100 * mmm) \t} J'ai prespécifié la variable de poids parce que j'essaie de minimiser la programmation que je suis de type. Parce que tous les jeux de données avec lesquels je travaille ont leur variable de poids étiquetée «poids», cela rend mon écriture un peu plus efficace. – deoksu

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

?

+0

Merci! réécrire ma fonction: > p.mean <- function (x) { \t mmm <-weighted.mean (x, = poids, na.rm = T) \t retour (rond (100 * mmm)) \t} fonctionne parfaitement. – deoksu

3

Try 'format':

options(digits=1) 

puis:

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

Vous pouvez également utiliser l'argument 'nPetite':

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

Et vous pouvez aussi essayer sprintf 'si vous êtes familier avec C.

1

la fonction sprintf() est grande pour le formatage de sortie numérique.

0

Le package siunitx peut également être utilisé pour formater des nombres en sweave.

Code pour Sweave

Le script suivant montre comment utiliser les numéros de format, la syntaxe est pour Sweave. Dans le préambule, vous pouvez définir votre formatage par défaut comme

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

puis la remplacer dans les commandes \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 pour knitr

En knitr par défaut, les numéros dans \ Sexpr sont arrondis lorsque l'option options(digits = 2) est définie. Mais si vous voulez un arrondi différent dans des endroits différents, le code suivant fonctionne, il doit être adapté car il n'y a pas besoin de double échappement d'antiglisse dans \ 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)) 
    } 
}