2010-04-05 64 views
9

Tôi thường phải tạo các ô xếp chồng xếp chồng để so sánh các biến, và vì tôi làm tất cả các chỉ số của mình trong R, tôi thích làm tất cả đồ họa của mình trong R với ggplot2. Tôi muốn tìm hiểu cách thực hiện hai việc:Làm cách nào để tạo biểu đồ thanh xếp chồng lên nhau tốt hơn với nhiều biến từ ggplot2?

Trước tiên, tôi muốn có thể thêm dấu tỷ lệ phần trăm thích hợp cho mỗi biến thay vì đánh dấu bằng số. Số lượng sẽ gây nhầm lẫn, đó là lý do tại sao tôi đưa ra các nhãn trục hoàn toàn.

Thứ hai, phải có cách đơn giản hơn để tổ chức lại dữ liệu của tôi để thực hiện điều này. Nó có vẻ như là loại điều tôi sẽ có thể làm tự nhiên trong ggplot2 với plyR, nhưng tài liệu cho plyR không phải là rất rõ ràng (và tôi đã đọc cả sách ggplot2 và tài liệu plyR trực tuyến.

Biểu đồ tốt nhất của tôi trông như thế này, các mã để tạo ra nó sau:

example graph

mã R tôi sử dụng để có được nó là như sau:

library(epicalc) 

### recode the variables to factors ### 
recode(c(int_newcoun, int_newneigh, int_neweur, int_newusa, int_neweco, int_newit, int_newen, int_newsp, int_newhr, int_newlit, int_newent, int_newrel, int_newhth, int_bapo, int_wopo, int_eupo, int_educ), c(1,2,3,4,5,6,7,8,9, NA), 
c('Very Interested','Somewhat Interested','Not Very Interested','Not At All interested',NA,NA,NA,NA,NA,NA)) 

### Combine recoded variables to a common vector 
Interest1<-c(int_newcoun, int_newneigh, int_neweur, int_newusa, int_neweco, int_newit, int_newen, int_newsp, int_newhr, int_newlit, int_newent, int_newrel, int_newhth, int_bapo, int_wopo, int_eupo, int_educ) 


### Create a second vector to label the first vector by original variable ### 
a1<-rep("News about Bangladesh", length(int_newcoun)) 
a2<-rep("Neighboring Countries", length(int_newneigh)) 
[...] 
a17<-rep("Education", length(int_educ)) 


Interest2<-c(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17) 

### Create a Weighting vector of the proper length ### 
Interest.weight<-rep(weight, 17) 

### Make and save a new data frame from the three vectors ### 
Interest.df<-cbind(Interest1, Interest2, Interest.weight) 
Interest.df<-as.data.frame(Interest.df) 

write.csv(Interest.df, 'C:\\Documents and Settings\\[name]\\Desktop\\Sweave\\InterestBangladesh.csv') 

### Sort the factor levels to display properly ### 

Interest.df$Interest1<-relevel(Interest$Interest1, ref='Not Very Interested') 
Interest.df$Interest1<-relevel(Interest$Interest1, ref='Somewhat Interested') 
Interest.df$Interest1<-relevel(Interest$Interest1, ref='Very Interested') 

Interest.df$Interest2<-relevel(Interest$Interest2, ref='News about Bangladesh') 
Interest.df$Interest2<-relevel(Interest$Interest2, ref='Education') 
[...] 
Interest.df$Interest2<-relevel(Interest$Interest2, ref='European Politics') 

detach(Interest) 
attach(Interest) 

### Finally create the graph in ggplot2 ### 

library(ggplot2) 
p<-ggplot(Interest, aes(Interest2, ..count..)) 
p<-p+geom_bar((aes(weight=Interest.weight, fill=Interest1))) 
p<-p+coord_flip() 
p<-p+scale_y_continuous("", breaks=NA) 
p<-p+scale_fill_manual(value = rev(brewer.pal(5, "Purples"))) 
p 
update_labels(p, list(fill='', x='', y='')) 

tôi muốn rất nhiều đánh giá cao bất cứ lời khuyên, thủ thuật hay gợi ý.

+0

Thay vì 'relevel' nhiều lần bạn có thể sử dụng một lần' yếu tố' bằng đối số 'nhãn'. Bạn cũng có thể kiểm tra 'sắp xếp lại' có thể sắp xếp các mức của bạn bằng một số biến (phần trăm" rất quan tâm "?) – Marek

+1

Màu sắc đẹp - nghĩ rằng tôi sẽ sử dụng các mẫu bia của tôi một ngày :-) – Andreas

+0

Bạn có muốn một luồng công việc sản xuất dữ liệu đi vào một biểu đồ như vậy cộng với có thể thêm các giá trị phần trăm trên đầu trang của mỗi nhóm điền vào mỗi thanh? – Jay

Trả lời

1

Về tỷ lệ phần trăm insted của ..count.., hãy thử:

ggplot(mtcars, aes(factor(cyl), prop.table(..count..) * 100)) + geom_bar() 

nhưng vì nó không phải là một ý tưởng tốt để xô một hàm vào aes(), bạn có thể viết chức năng tùy chỉnh để tạo ra tỷ lệ ra khỏi ..count.., vòng nó để n số thập phân, v.v.

Bạn gắn nhãn bài đăng này với plyr, nhưng tôi không thấy bất kỳ plyr nào đang hoạt động tại đây và tôi đặt cược rằng ddply() có thể thực hiện công việc. Tài liệu trực tuyến plyr sẽ đủ.

1

Nếu tôi hiểu bạn một cách chính xác, để khắc phục vấn đề ghi nhãn trục thực hiện thay đổi sau đây:

# p<-ggplot(Interest, aes(Interest2, ..count..)) 
p<-ggplot(Interest, aes(Interest2, ..density..)) 

Đối với một thứ hai, tôi nghĩ rằng bạn sẽ khấm khá hơn làm việc với reshape package. Bạn có thể sử dụng nó để tổng hợp dữ liệu thành các nhóm rất dễ dàng.

Trong tài liệu tham khảo để bình luận aL3xa của dưới đây ...

library(ggplot2) 
r<-rnorm(1000) 
d<-as.data.frame(cbind(r,1:1000)) 
ggplot(d,aes(r,..density..))+geom_bar() 

Returns ...

alt text http://www.drewconway.com/zia/wp-content/uploads/2010/04/density.png

Các thùng hiện nay mật độ ...

+0

Bạn đã thử cú pháp của mình chưa? Bạn đã bỏ qua một lớp 'geom_bar' ... tuy nhiên, nếu bạn chuyển' ..density..' bằng 'geom_bar', bạn sẽ nhận được một số thanh có kích thước bằng nhau. Hãy thử thêm 'geom_bar()' và xem điều gì xảy ra. – aL3xa

+0

Hoạt động tốt, xem ở trên – DrewConway

+0

Nó hoạt động tốt với các vars liên tục nhưng tạo ra các thanh có độ dài đầy đủ với các yếu tố và vectơ ký tự, có lẽ vì việc tính toán mật độ không biết phải làm gì với x không liên tục. Thay thế 'r' bằng cái gì đó như' f <- mẫu (c ("Đồng ý", "Không có ý kiến", "Không đồng ý"), kích thước = 1000, thay thế = TRUE, prob = c (.2, .5, .3)) '. Tôi đã chạy vào điều này một số lần trước, bởi vì tôi thích biểu đồ mật độ và tôi thích ggplot, nhưng tôi đã không tìm ra cách để làm cho nó hoạt động được (mặc dù tôi đã không cố gắng rất khó, một trong hai). –

1

câu hỏi đầu tiên của bạn: Sẽ sự giúp đỡ này?

geom_bar(aes(y=..count../sum(..count..))) 

Câu hỏi thứ hai của bạn; bạn có thể sử dụng sắp xếp lại để sắp xếp các thanh không?Một cái gì đó như

aes(reorder(Interest, Value, mean), Value) 

(vừa trở về từ một ổ đĩa Bảy giờ - đã quá mệt mỏi - nhưng tôi đoán nó nên làm việc)

+0

xin lỗi - Tôi cho rằng bạn đã có một khung dữ liệu bị tan chảy. – Andreas

2

Bạn không cần prop.tables hoặc đếm vv để làm các thanh xếp chồng lên nhau 100%. Bạn chỉ cần +geom_bar(position="stack")

2

Vấn đề thứ hai của bạn có thể được giải quyết với tan chảy và đúc từ Reshape gói

Sau khi bạn đã yếu tố các yếu tố trong data.frame bạn gọi là bạn có thể sử dụng một cái gì đó như:

install.packages("reshape") 
library(reshape) 

x <- melt(your.df, c()) ## Assume you have some kind of data.frame of all factors 
x <- na.omit(x) ## Be careful, sometimes removing NA can mess with your frequency calculations 

x <- cast(x, variable + value ~., length) 
colnames(x) <- c("variable","value","freq") 
## Presto! 
ggplot(x, aes(variable, freq, fill = value)) + geom_bar(position = "fill") + coord_flip() + scale_y_continuous("", formatter="percent") 

Là một sang một bên, tôi thích sử dụng grep để kéo vào cột từ một nhập khẩu lộn xộn. Ví dụ:

x <- your.df[,grep("int.",df)] ## pulls all columns starting with "int_" 

Và việc thanh toán dễ dàng hơn khi bạn không phải nhập c ('', ...) một triệu lần.

for(x in 1:ncol(x)) { 
df[,x] <- factor(df[,x], labels = strsplit(' 
Very Interested 
Somewhat Interested 
Not Very Interested 
Not At All interested 
NA 
NA 
NA 
NA 
NA 
NA 
', '\n')[[1]][-1] 
} 
Các vấn đề liên quan