2010-03-21 33 views
7

Tôi đang gặp vấn đề về lập trình R cho Sweave và nhóm #rstats twitter thường trỏ đến đây, vì vậy tôi nghĩ tôi sẽ đặt câu hỏi này cho đám đông SO. Tôi là một nhà phân tích, không phải là một lập trình viên - vì vậy hãy dễ dàng đăng bài đầu tiên của tôi.Lập trình R/Sweave cho thích hợp Sexpr đầu ra

Đây là vấn đề: Tôi đang soạn thảo báo cáo khảo sát trong Sweave with R và muốn báo cáo lợi nhuận biên trong hàng sử dụng \Sexpr{}. Ví dụ: thay vì nói:

Chỉ 14% người trả lời cho biết 'X'.

Tôi muốn viết báo cáo như thế này:

Chỉ \ Sexpr {p.mean (variable)} $ \% $ số người được hỏi cho biết 'X'.

Vấn đề là Sweave chuyển đổi kết quả của biểu thức trong \Sexpr{} thành chuỗi ký tự, có nghĩa là đầu ra từ biểu thức trong R và đầu ra xuất hiện trong tài liệu của tôi khác nhau. Ví dụ, ở trên tôi sử dụng chức năng 'p.mean':

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

Trong R, đầu ra trông như thế này:

p.mean(variable) 
>14 

nhưng khi tôi sử dụng \Sexpr{p.mean(variable)} , Tôi nhận được một chuỗi ký tự unrounded (trong trường hợp này: 13.5857142857143) trong tài liệu của tôi. Tôi đã cố gắng để giới hạn đầu ra của chức năng của tôi để digits=1 trong môi trường toàn cầu, trong chức năng chính nó, và và trong các lệnh khác nhau. Nó chỉ có vẻ chứa những gì R in, không phải là chuyển đổi nhân vật đó là kết quả của biểu thức và cuối cùng in trong tập tin LaTeX.

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

Có ai biết những gì tôi có thể làm gì để hạn chế các chữ số in trong file LaTeX, hoặc bằng cách tái lập trình các chức năng R hoặc với một thiết lập trong Sweave hoặc \Sexpr{}?

Trả lời

4

@KennyTM đã hiểu. @ David, bạn nên tránh options(digits = 1) vì nó sẽ ảnh hưởng đến tất cả các tính toán của bạn (nó sẽ ngăn chặn số thập phân trong mỗi đầu ra sau đó). Vì vậy, hãy sử dụng chức năng round() sau khi áp dụng weighted.mean().Một cái gì đó như thế này:

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

không sử dụng print(), nhưng return(). Dưới đây là lý do:

> 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 

Sử dụng return() hoặc chỉ cần gõ biến dẫn đến dòng cuối cùng:

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

Vì vậy, viết lại chức năng của bạn, và hãy chắc chắn để sử dụng as.character() ... bạn có tất cả các bit , bây giờ chỉ cần đặt tất cả lại với nhau.

P.S.

Tôi không chắc chắn cách bạn hoạt động ... Tôi chưa bao giờ sử dụng ý nghĩa cân nhắc trong phân tích của mình. Hơi khó hiểu nhất là weight=weight. Nó sẽ không được đẹp hơn để đặt một đối số nhiều hơn trong chức năng? Thành thật mà nói, tôi vẫn ngạc nhiên bởi thực tế là chức năng của bạn đang cho bạn kết quả đúng ... có lẽ bởi vì bạn có weight biến được xác định trước định nghĩa hàm. [EDIT] Bạn sẽ không lấy giá trị trung bình có trọng số với hàm của bạn nếu bạn không có hàm weight được xác định trước, nhưng có nghĩa là "thông thường"!

Tôi hy vọng điều này đã giúp bạn!

Trân trọng! Aleksandar

+0

Cảm ơn, Aleksandar.Tôi viết lại chức năng như sau: p.mean <- function (x) { \t mmm <-weighted.mean (x, weight = weight, na.rm = T) \t return (tròn (100 * mmm)) \t} Tôi đã xác định trước biến trọng số vì tôi đang cố gắng thu nhỏ chương trình khi tôi nhập. Bởi vì tất cả các tập dữ liệu mà tôi làm việc có biến trọng số của họ có nhãn 'trọng lượng', điều này làm cho văn bản của tôi chỉ là một chút hiệu quả hơn. – deoksu

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

?

+0

Cảm ơn! viết lại hàm của tôi tới: > p.mean <- function (x) { \t mmm <-weighted.mean (x, weight = weight, na.rm = T) \t return (tròn (100 * mmm)) \t} hoạt động hoàn hảo. – deoksu

3

Try 'định dạng':

options(digits=1) 

và sau đó:

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

Bạn cũng có thể sử dụng 'nsmall' đối số:

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

Và bạn cũng có thể thử 'sprintf 'nếu bạn quen thuộc với C.

1

các sprintf() chức năng là rất tốt cho định dạng đầu ra số.

0

Gói siunitx cũng có thể được sử dụng để định dạng các số trong sweave.

Mã cho Sweave

Các kịch bản sau đây cho thấy làm thế nào để sử dụng nó để định dạng số, cú pháp là cho Sweave. Trong lời mở đầu, bạn có thể thiết lập mặc định của bạn định dạng như

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

và sau đó ghi đè lên nó trong lệnh \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

Mã cho knitr

trong knitr theo mặc định, các con số trong \ Sexpr được làm tròn khi tùy chọn options(digits = 2) được đặt. Nhưng nếu bạn muốn làm tròn khác nhau ở các vị trí khác nhau, mã sau hoạt động, nó cần phải được điều chỉnh vì không cần phải tăng gấp đôi khả năng chống trộm trong \ Sexpr trong 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)) 
    } 
} 
Các vấn đề liên quan