2013-01-22 33 views
13

Tôi cần áp dụng cut trên biến liên tục để hiển thị nó với thang màu Brewer trong ggplot2, như trong Setting breakpoints for data with scale_fill_brewer() function in ggplot2. Biến liên tục là sự khác biệt tương đối và tôi muốn định dạng dữ liệu là "18,2%" thay vì "0,182". Có cách nào dễ dàng để đạt được điều này?Định dạng nhãn được tạo bởi cut() theo tỷ lệ phần trăm

x <- runif(100) 
levels(cut(x, breaks=10)) 

[1] "(0.0223,0.12]" "(0.12,0.218]" "(0.218,0.315]" "(0.315,0.413]" 
[5] "(0.413,0.511]" "(0.511,0.608]" "(0.608,0.706]" "(0.706,0.804]" 
[9] "(0.804,0.901]" "(0.901,0.999]" 

Tôi muốn, ví dụ: mức đầu tiên xuất hiện là (2.23 %, 12 %]. Có cách nào tốt hơn để thay thế cho cut?

+1

+1 cho tiêu đề câu hỏi rõ ràng, mã có thể tái sản xuất và mục tiêu rõ ràng về nội dung mong muốn. Mọi người có thể học hỏi từ bài đăng này. –

Trả lời

15

tôi đã thực hiện cut_format() trong phiên bản 0,2-3 của gói kimisc tôi, phiên bản 0.3 là trên cran bây giờ.

# devtools::install_github("krlmlr/kimisc") 
x <- seq(0.1, 0.9, by = 0.2) 

breaks <- seq(0, 1, by = 0.25) 

cut(x, breaks) 
## [1] (0,0.25] (0.25,0.5] (0.25,0.5] (0.5,0.75] (0.75,1] 
## Levels: (0,0.25] (0.25,0.5] (0.5,0.75] (0.75,1] 

cut_format(x, breaks, format_fun = scales::percent) 
## [1] (0%, 25%] (25%, 50%] (25%, 50%] (50%, 75%] (75%, 100%] 
## Levels: (0%, 25%] (25%, 50%] (50%, 75%] (75%, 100%] 

Vẫn chưa hoàn hảo, vượt qua số lần ngắt (như trong ví dụ ban đầu) chưa hoạt động.

+0

Điều này thật tuyệt vời !!! – novice

8

Sử dụng gsub với một số regex sau nhân dữ liệu gốc của bạn bằng 100:

gsub("([0-9.]+)","\\1%",levels(cut(x*100,breaks=10))) 
[1] "(0.449%,10.4%]" "(10.4%,20.3%]" "(20.3%,30.2%]" "(30.2%,40.2%]" "(40.2%,50.1%]" "(50.1%,60%]" "(60%,69.9%]" "(69.9%,79.9%]" "(79.9%,89.8%]" "(89.8%,99.7%]" 
+0

Chỉ cần hack một điều tương tự, quá. Tôi nghĩ rằng phải có một cách tốt hơn :-) – krlmlr

+0

Tôi nghĩ rằng đó có lẽ là cách dễ nhất kể từ đó, nhân với 100 bước sẽ khó làm khi bạn đã tạo ra các nhãn văn bản. – James

+0

Tôi đã suy nghĩ về một cái gì đó dọc theo 'cắt (x, nhãn = chức năng (lo, hi) paste0 (...))' ... – krlmlr

5

Tại sao không sao chép mã cho cut.default và tạo ra phiên bản của riêng bạn với mức sửa đổi? Xem this gist.

Hai dòng đã được thay đổi:

Dòng 22: ch.br <- formatC(breaks, digits = dig, width = 1) đổi thành ch.br <- formatC(breaks*100, digits = dig, width = 1).

Dòng 29: else "[", ch.br[-nb], ",", ch.br[-1L], if (right) đổi thành else "[", ch.br[-nb], "%, ", ch.br[-1L], "%", if (right)

Phần còn lại là như nhau. Và tại đây hoạt động:

library(devtools) 
source_gist(4593967) 

set.seed(1) 
x <- runif(100) 
levels(cut2(x, breaks=10)) 
# [1] "(1.24%, 11%]" "(11%, 20.9%]" "(20.9%, 30.7%]" "(30.7%, 40.5%]" "(40.5%, 50.3%]" 
# [6] "(50.3%, 60.1%]" "(60.1%, 69.9%]" "(69.9%, 79.7%]" "(79.7%, 89.5%]" "(89.5%, 99.3%]" 
+0

Tôi đã quản lý để làm điều đó bằng cách sử dụng một thay đổi một dòng chỉ: https: // gist.github.com/4594243. Tuy nhiên, điều này sẽ mất khoảng trống sau ',', trong đó tham số thứ hai để 'cắt' sẽ được yêu cầu. Sẽ đề xuất mở rộng 'cut.default' của R nếu không có gì khác xuất hiện. – krlmlr

2

Câu trả lời mới cho câu hỏi cũ.

Bạn có thể sử dụng đối số label để chuyển một hàm để định dạng nhãn. Tôi sẽ sử dụng gsubfnscales::percent

library(gsubfn) 
library(scales) 
pcut <- function(x) gsubfn('\\d\\.\\d+', function(x) percent(as.numeric(x)),xx) 
d <- data.frame(x=runif(100)) 

ggplot(d,aes(x=x,y=seq_along(x))) + 
geom_point(aes(colour = cut(x, breaks = 10))) + 
scale_colour_brewer(name = 'x', palette = 'Spectral', label = pcut) 

enter image description here

+0

Cảm ơn bạn đã nhập, đó thực sự là một lựa chọn tốt khác. Tôi vừa đăng những suy nghĩ của tôi về các biến chứng với dữ liệu binning ở đây: http://stackoverflow.com/a/17438591/946850. Vấn đề chính là dữ liệu, thuật toán cắt, số lần ngắt và bảng màu ảnh hưởng lẫn nhau, nhưng nằm rải rác xung quanh một số lệnh gọi hàm khác nhau. Đây có phải là một phần của gói R không, bạn nghĩ sao? – krlmlr

+0

@krlmlr Có, nhưng tôi thường đi xuống đường 'scale_colour_gradientn' như' ggplot (d, aes (x = x, y = seq_along (x))) geom_point (aes (color = x)) + scale_colour_gradientn (màu sắc = brewer.pal ('Spectral', n = 10), label = percent) '- sẽ giết một số mèo con. – mnel

+0

Có, và tất nhiên thậm chí còn có [yêu cầu kéo] (https://github.com/hadley/ggplot2/pull/439) giải quyết vấn đề này, sau đó phải là loại máy giết người kitten. Tôi đã cân nhắc việc sử dụng nó, nhưng bây giờ tôi thấy cách tiếp cận discretization/cutting/binning rõ ràng hơn. Nó chỉ là, hiện nay, có vẻ như không có ký hiệu gọn gàng cho việc này. – krlmlr

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