与えられた国の値に対応するグラデーションカラーで地図上にプロットしたい次の簡単なサンプルデータがあります。
ddf = read.table(text="
country value
USA 10
UK 30
Sweden 50
Japan 70
China 90
Germany 100
France 80
Italy 60
Nepal 40
Nigeria 20
", header=T)
グーグル検索で、私はいくつかのサイトを見つけました。しかし、私は小さくて明確で、できれば高速であるはずのコードを探しています(ggplotメソッドは比較的遅いことがわかりました)。世界地図の解像度は高くなくてもかまいません。
私は次のコードを試しました:
library(maptools)
data(wrld_simpl)
plot(wrld_simpl)
特定の国は次のように色付けできます: [R]マップパッケージを使用-世界地図上の特定の国で色付け コマンドを使用:
plot(wrld_simpl, col = c(gray(.80), "red")[grepl("^U", wrld_simpl@data$NAME) + 1])
しかし、どうすれば上記のデータを色のグラデーションでマップを取得できますか。ご協力いただきありがとうございます。
より少ないコードとより粗い解像度のマップが必要な場合は、rworldmapを使用できます。
library(rworldmap)
#create a map-shaped window
mapDevice('x11')
#join to a coarse resolution map
spdf <- joinCountryData2Map(ddf, joinCode="NAME", nameJoinColumn="country")
mapCountryData(spdf, nameColumnToPlot="value", catMethod="fixedWidth")
デフォルトの分類、色、凡例は変更できます。こちらをご覧ください RJournal paper 。
名前よりも国コードの方が高速です。
「遅い」を定義します。 ggplotは、数秒余分にコストをかけてマップ上にデータを表示するための最も柔軟な方法の1つを提供します。
library(RColorBrewer)
library(maptools)
library(ggplot2)
data(wrld_simpl)
ddf = read.table(text="
country value
'United States' 10
'United Kingdom' 30
'Sweden' 50
'Japan' 70
'China' 90
'Germany' 100
'France' 80
'Italy' 60
'Nepal' 40
'Nigeria' 20", header=TRUE)
# Pascal had a #spiffy solution that is generally faster
plotPascal <- function() {
pal <- colorRampPalette(brewer.pal(9, 'Reds'))(length(ddf$value))
pal <- pal[with(ddf, findInterval(value, sort(unique(value))))]
col <- rep(grey(0.8), length(wrld_simpl@data$NAME))
col[match(ddf$country, wrld_simpl@data$NAME)] <- pal
plot(wrld_simpl, col = col)
}
plotme <- function() {
# align colors to countries
ddf$brk <- cut(ddf$value,
breaks=c(0, sort(ddf$value)),
labels=as.character(ddf[order(ddf$value),]$country),
include.lowest=TRUE)
# this lets us use the contry name vs 3-letter ISO
wrld_simpl@data$id <- wrld_simpl@data$NAME
wrld <- fortify(wrld_simpl, region="id")
wrld <- subset(wrld, id != "Antarctica") # we don't rly need Antarctica
gg <- ggplot()
# setup base map
gg <- gg + geom_map(data=wrld, map=wrld, aes(map_id=id, x=long, y=lat), fill="white", color="#7f7f7f", size=0.25)
# add our colored regions
gg <- gg + geom_map(data=ddf, map=wrld, aes(map_id=country, fill=brk), color="white", size=0.25)
# this sets the scale and, hence, the legend
gg <- gg + scale_fill_manual(values=colorRampPalette(brewer.pal(9, 'Reds'))(length(ddf$value)),
name="Country")
# this gives us proper coords. mercator proj is default
gg <- gg + coord_map()
gg <- gg + labs(x="", y="")
gg <- gg + theme(plot.background = element_rect(fill = "transparent", colour = NA),
panel.border = element_blank(),
panel.background = element_rect(fill = "transparent", colour = NA),
panel.grid = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
legend.position = "right")
gg
}
system.time(plotme())
## user system elapsed
## 1.911 0.005 1.915
system.time(plotthem())
## user system elapsed
## 1.125 0.014 1.138
Ggplotコードは、次のマップを生成します。
タイミングは実行ごとに異なりますが、1分以上離れていることはありません(私のシステムでは平均0.6mのように見えましたが、広範なベンチマークを実行するつもりはありませんでした)。
更新
要件が引き続き引き出されているため、離散スケールを連続スケールに簡単に置き換えることができます。
pal <- colorRampPalette(brewer.pal(9, 'Reds'))(length(ddf$value))
palSz <- 10 # not sure what you really want/need for this range
gg <- gg + scale_fill_gradient2(low = pal[1],
mid = pal[palSz/2],
high = pal[palSz],
midpoint = (max(ddf$value) + min(ddf$value)) / 2,
name="value")
ただし、複雑さを抽象化するため、@ Andyのrworldmap
を使用する必要があるようです。
おそらく最適化されていません:
library(RColorBrewer)
library(maptools)
data(wrld_simpl)
ddf = read.table(text="
country value
'United States' 10
'United Kingdom' 30
'Sweden' 50
'Japan' 70
'China' 90
'Germany' 100
'France' 80
'Italy' 60
'Nepal' 40
'Nigeria' 20", header=TRUE)
Reds
はカラーパレットの名前です。見る ?brewer.pal
他の利用可能なパレットの場合。
pal <- colorRampPalette(brewer.pal(9, 'Reds'))(length(ddf$value))
pal <- pal[with(ddf, findInterval(value, sort(unique(value))))]
col <- rep(grey(0.8), length(wrld_simpl@data$NAME))
col[match(ddf$country, wrld_simpl@data$NAME)] <- pal
plot(wrld_simpl, col = col)