2011-11-07 36 views
7

Tôi có một loạt biểu đồ ggplot mà tôi đang lặp lại với một vài biến thể nhỏ. Tôi muốn bọc các qplots này với các tùy chọn của chúng vào một hàm để tránh nhiều sự lặp lại trong mã.Viết các hàm ggplot trong R với các đối số tùy chọn

Vấn đề của tôi là đối với một số biểu đồ tôi đang sử dụng tùy chọn + facet_wrap(), nhưng đối với những người khác thì không. I E. Tôi cần bọc mặt để trở thành một đối số tùy chọn. Khi nó được bao gồm mã cần gọi + facet_wrap() với biến được cung cấp trong đối số facets.

Vì vậy, lý tưởng chức năng của tôi sẽ giống như thế này, với khía cạnh là một đối số tùy chọn:

$ qhist(variable, df, heading, facets) 

Tôi đã thử googling cách thêm đối số tùy chọn và họ đề nghị hoặc thông qua một giá trị mặc định hoặc sử dụng một nếu vòng lặp với hàm missing(). Tôi đã không thể có được một trong hai để làm việc.

Đây là hàm tôi đã viết, với chức năng mong muốn của đối số khía cạnh tùy chọn cũng được bao gồm.

$ qhist <- function(variable, df, heading, facets) { 
     qplot(variable, data = df, geom = "histogram", binwidth = 2000, 
      xlab = "Salary", ylab = "Noms") + 
     theme_bw() + 
     scale_x_continuous(limits=c(40000,250000), 
       breaks=c(50000,100000,150000,200000,250000), 
       labels=c("50k","100k","150k","200k","250k")) + 
     opts(title = heading, plot.title = theme_text(face = "bold", 
      size = 14), strip.text.x = theme_text(size = 10, face = 'bold')) 
     # If facets argument supplied add the following, else do not add this code 
     + facet_wrap(~ facets) 
+0

Các mặt 'hợp lý' có hợp lý không?Hay cái gì khác? (vector ký tự của các biến để khía cạnh?) –

+0

Không, nó sẽ là một biến để khía cạnh. Vì vậy, ví dụ tôi có biểu đồ dữ liệu tiền lương, và đôi khi tôi muốn khía cạnh đó theo ngành. –

Trả lời

11

cách để thiết lập một mặc định là như thế này:

testFunction <- function(requiredParam, optionalParam=TRUE, alsoOptional=123) { 
    print(requiredParam) 
    if (optionalParam==TRUE) print("you kept the default for optionalParam") 
    paste("for alsoOptional you entered", alsoOptional) 
} 

* EDIT *

Oh, ok ... vì vậy tôi nghĩ rằng tôi có một ý tưởng tốt hơn về những gì bạn đang yêu cầu. Có vẻ như bạn không chắc chắn cách đưa phần tử tùy chọn vào đối tượng ggplot. Làm thế nào về điều này:

qhist <- function(variable, df, heading, facets=NULL) { 
    d <- qplot(variable, data = df, geom = "histogram", binwidth = 2000, 
     xlab = "Salary", ylab = "Noms") + 
    theme_bw() + 
    scale_x_continuous(limits=c(40000,250000), 
      breaks=c(50000,100000,150000,200000,250000), 
      labels=c("50k","100k","150k","200k","250k")) + 
    opts(title = heading, plot.title = theme_text(face = "bold", 
     size = 14), strip.text.x = theme_text(size = 10, face = 'bold')) 
    # If facets argument supplied add the following, else do not add this code 
    if (is.null(facets)==FALSE) d <- d + facet_wrap(as.formula(paste("~", facets))) 
    d 
    return(d) 
    } 

Tôi chưa thử nghiệm mã này cả. Nhưng ý tưởng chung là facet_wrap mong đợi một công thức, vì vậy nếu các khía cạnh được chuyển thành một chuỗi ký tự, bạn có thể xây dựng một công thức với as.formula() và sau đó thêm nó vào đối tượng lô.

Nếu tôi đã làm điều đó, tôi sẽ có chức năng chấp nhận một công thức khía cạnh tùy chọn và sau đó chuyển công thức khía cạnh đó trực tiếp vào facet_wrap. Điều đó sẽ phủ nhận sự cần thiết cho cuộc gọi as.formula() để chuyển đổi văn bản thành công thức.

+0

cổ vũ, tôi nghĩ rằng tôi nhận được rằng, tôi đoán tôi vẫn không hiểu làm thế nào để sử dụng cấu trúc đó để sau đó bao gồm các tùy chọn trong mã được gọi là bởi các chức năng. Tôi sẽ cập nhật câu hỏi của mình để phản ánh điều đó. –

+0

Trong cơ thể chức năng của bạn, hãy thử một cái gì đó như 'res <- qplot (...) + ...; if (facets) res <- res + facet_wrap (~ các khía cạnh); return (res) ' – Tyler

+0

Cho phép đánh giá không chuẩn của' biến' trong 'qplot', bạn sẽ tốt hơn với cú pháp' ggplot' và sử dụng 'aes_string':' d <- ggplot (dữ liệu = df, aes_string (x = biến)) + geom_histogram (binwidth = 2000) + ... ' –

2

Lưu ý rằng bạn cũng có thể sử dụng missing(facets) để kiểm tra xem đối số khía cạnh đã được chỉ định hay chưa. Nếu bạn sử dụng giải pháp @JD Long, nó sẽ giống như thế này:

qhist <- function(variable, df, heading, facets) { 
    ... insert @JD Longs' solution ... 

    if (!missing(facets)) d <- d + facet_wrap(as.formula(paste("~", facets))) 
    return(d) 
} 

... Lưu ý rằng tôi cũng đã thay đổi đối số mặc định từ facets=NULL chỉ facets.

Nhiều chức năng R sử dụng các đối số bị thiếu như thế này, nhưng nói chung tôi thích biến thể của @JD Long sử dụng giá trị đối số mặc định (như NULL hoặc NA) khi có thể. Nhưng đôi khi không có giá trị mặc định tốt ...

+0

Cảm ơn bạn đã cung cấp tùy chọn khác. Tôi đã nhìn thấy điều này xung quanh, nhưng tôi không thể làm việc ra làm thế nào để bao gồm nó trong chức năng cụ thể của tôi. –

3

Có lẽ, cách tốt nhất là ngừng sử dụng các tên biến bất thường như dấu phẩy hoặc dấu cách.

Như một giải pháp thay thế, đây là phần mở rộng của câu trả lời của @ JDLong. Bí quyết là đổi tên biến facet.

f <- function(dat, facet = NULL) { 
    if(!missing(facet)) { 
     names(dat)[which(names(dat) == facet)] <- ".facet." 
     ff <- facet_wrap(~.facet.) 
    } else { 
     ff <- list() 
    } 
    qplot(x, y, data = dat) + ff 
} 

d <- data.frame(x = 1:10, y = 1:10, "o,o" = gl(2,5), check.names=F) 

f(d, "o,o") 
f(d) 
+0

Xin lỗi 'Thương mại bán lẻ' thực sự là một trong những chuỗi trong biến. Biến tự nó được đặt tên là 'công nghiệp'. –

+0

Sau đó, nó không gây ra bất kỳ lỗi nào. Có thể có một số sai lầm trong cách bạn sử dụng. Bạn có thể đính kèm một ví dụ tái sản xuất được không? – kohske

+0

bạn nói đúng. Vấn đề của tôi là tôi không kèm theo đối số như một chuỗi. –

Các vấn đề liên quan