Ở 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