2010-03-21 3 views
7

У меня немного проблемное программирование R для Sweave, и группа #rstats twitter часто указывает здесь, поэтому я подумал, что поставил бы этот вопрос в толпу SO. Я аналитик, а не программист, так что легко на первом посту.Программирование R/Sweave для правильного вывода Sexpr

Возникла проблема: я составляю отчет об исследовании в Sweave с R и хотел бы сообщить о предельных доходах в строке, используя \Sexpr{}. Например, вместо того, чтобы говорить:

Только 14% респондентов сказали «Х».

Я хочу написать отчет, как это:

только \ Sexpr {p.mean (переменная)} $ \% $ респондентов сказали, что '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" 

Кто-нибудь знает, что я могу сделать, чтобы ограничить цифры, напечатанные в файле LaTeX, либо путем перепрограммирования функции R или с установкой в ​​Sweave или \Sexpr{}?

ответ

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, определенная до определения функции. [EDIT] Вы не будете получите средневзвешенное значение с вашей функцией, если у вас нет weight функция предопределена, но «регулярная» означает!

Я надеюсь, что это помогло вам!

С наилучшими пожеланиями, Александарами

+0

Спасибо, Александар.Я переписал функцию как это: p.mean <- функция (х) { \t ттт <-weighted.mean (х, вес = вес, na.rm = Т) \t возврата (круглые (100 * ттт)) \t} Я предсказывал переменную веса, потому что я пытаюсь свести к минимуму программирование, поскольку я являюсь типом. Поскольку все наборы данных, с которыми я работаю, имеют свою переменную веса с надписью «вес», это делает мое письмо чуть более эффективным. – deoksu

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

?

+0

Спасибо! переписывание моей функции: > p.mean <- функция (х) { \t ттт <-weighted.mean (х, вес = вес, na.rm = Т) \t возврата (круглый (100 * ттт)) \t} работает отлично. – deoksu

3

'Формат' Try:

options(digits=1) 

, а затем:

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

Вы также можете использовать 'nsmall' аргумент:

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

И вы также можете попробовать «Sprintf ', если вы знакомы с C.

1

функции Sprintf() отлично подходит для форматирования числового вывода.

0

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} 

enter image description here

Код для knitr

В knitr по умолчанию номера in \ Sexpr округлены, когда установлен параметр options(digits = 2). Но если вы хотите различное округление в разных местах, следующий код работает, его нужно адаптировать, так как нет необходимости удваивать антиспали в \ Sexpr в 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)) 
    } 
} 
Смежные вопросы