Friday, 21 April 2017

bài trước, mình có chia sẻ cách vẽ biểu đồ histogram về chỉ tiêu phân bố số cây rừng theo cỡ đường kính (N/D) của một số trạng thái rừng tự nhiên bằng R. Trong cái note này, mình cũng đề cập đến biểu đồ phân bố N/D. Tuy nhiên, có một vấn đề phát sinh mà mình đã mất tương đối khá thời gian (hơn một ngày trời) cho vấn đề này.

Cỡ kính ở trong cái note này bao gồm:
> Co_kinh= c("<10","10-15","15-20","20-25","25-30","30-35","35-40","40-45","45-50","50-55","55-60","60-65","65-70","70-75","75-80","80-85","85-90","90-95","95-100",">100")
Trong bài trước, mình nói thay vì viết “>60” bằng “Tren 60” để yêu cầu nghiêm ngặt về văn phạm trong R cũng chưa thực sự chuẩn. Bởi, ở bài này mình vẫn để các cỡ kính, trong đó, có cỡ “<10” và “>100”, khi thao tác trong R vẫn ok. Tuy nhiên, cũng gặp rắc rối một chút, nhưng không sao, mình đã khắc phục được điều đó.

Cái khác ở cái note này là cỡ kính nhiều hơn (chia ra 20 cỡ kính), trong đó, có cỡ kính cận dưới (<10cm) và cỡ kính cận trên (>100cm) cần được lưu ý. Khi thực hiện các lệnh trong R nó không theo ý muốn như thao tác trên Excel. Bởi, phải tuân thủ các “văn phạm” trong R. Chúng mình cùng bắt đầu nhé.

Vẽ biểu đồ phân bố N/D bình thường:
> s1=ggplot(data=ND, aes(x=Co_kinh, y=D, fill=Location))+geom_bar(position="dodge", stat="identity")+ theme_bw()+ theme_classic()+ geom_rangeframe()+ theme_tufte()+ scale_y_continuous(breaks = extended_range_breaks()(ND$D))+theme(legend.position = "none")+ theme(axis.text.x=element_text(angle = 90))+labs(title="Hình 1")
Chúng ta thấy, cỡ kính “<10”, “10-15”, và “15-20” nằm ở cuối cùng của trục x, tức là, không theo thứ tự từ nhỏ đến lớn. Bởi, dấu “<” và “>” (hình 1).
Nếu bạn có thêm các layer như thông thường:
scale_x_continuous(breaks = extended_range_breaks()(Son_ND$Co_kinh))
Kết quả là:
Error in Summary.factor(c(25L, 26L, 27L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L,  : 
  ‘min’ not meaningful for factors
Hoặc layer:
scale_x_continuous(labels = c("<10","10-15","15-20","20-25","25-30","30-35","35-40","40-45","45-50","50-55","55-60","60-65","65-70","70-75","75-80","80-85","85-90","90-95","95-100",">100"))
R thông báo:
Error: Discrete value supplied to continuous scale
Nói chung là mình đã mất nhiều thời gian cho vấn đề này, tưởng chừng rơi vào bế tắc. Thật may. Hôm nay, sau khi thử đủ cách, tìm hiểu trên mạng mới biết được cách khắc phục cho nhược điểm này. Hãy cùng áp dụng nhé:
Đầu tiên, mình cần thêm một biến, tạm gọi là biến “thứ tự”. Như sau:
> tt=c("1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20")
Sau đó, nhập vào data vừa mới vẽ bên trên:
> SND=data.frame(ND,tt)
Bây giờ ta có một data mới (SND) có thêm biến thứ thự (tt), với mục đích là yêu cầu R sắp xếp theo thứ tự mà mình yêu cầu. Thứ tự này tương ứng với các cỡ kính: “1”= “<10”, “2” = “10-15”... “20”= “>100”.
Sau khi đã tạo ra một data mới, có chứa biến thứ tự. Chúng ta, phải yêu tạo ra một objiect khác, theo thứ tự từ 1:20 và dùng hàm: transform()
> NDD=transform(SND, aes(Co_kinh=reorder(Co_kinh,tt))
Mục đích của việc dùng hàm transform()là yêu cầu vẽ biến Co_kinh theo thứ tự từ 1:20, tương ứng với các cỡ kính từ: “<10” đến “>100”.
Bây giờ bạn thêm layer: scale_x_discrete(limits) như sau:
> s1=ggplot(data=NDD, aes(x=tt, y=D, fill=Location))+geom_bar(position="dodge", stat="identity")+ theme_bw()+ theme_classic()+ geom_rangeframe()+ theme_tufte()+ scale_y_continuous(breaks = extended_range_breaks()(NDD$D))
> s2=s1+scale_x_discrete(limits=c("<10","10-15","15-20","20-25","25-30","30-35","35-40","40-45","45-50","50-55","55-60","60-65","65-70","70-75","75-80","80-85","85-90","90-95","95-100",">100"))
> s3=s2+ xlab("C kính, cm")+ ylab("N/D")+ theme(legend.position = "top")+theme(axis.text.x=element_text(angle = 90))
Bạn có thể nhận thấy, bây giờ cỡ kính đã được sắp từ nhỏ đến lớn như mong muốn của người vẽ, cũng tương tự dễ thấy như vẽ trong Excel.

Trên đây mình có gặp vấn đề về vẽ biểu đồ phân bố N/D theo cỡ kính, trong đó, cỡ kính “<10” và cỡ kính “>100” là một trong những trở ngại mà R không theo yêu cầu của người vẽ. Để khắc phục nhược điểm đó các bạn thêm:
-       tt=c("1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20")
-       > SND=data.frame(ND,tt)
-       > NDD=transform(SND, aes(Co_kinh=reorder(Co_kinh,tt))
-       scale_x_discrete(limits)

Các bạn có thể thực hành theo những gì mình đề cập bên trên nhé. Hoặc có cách nào khác cũng xin chia sẻ để mình cùng học nhé. Trân trọng!

0 nhận xét:

Post a Comment

Powered by Blogger.

Contact Form

Name

Email *

Message *

Pages - Menu

Popular

Total Pageviews

Popular Posts

Recent Posts

Text Widget