Menggabungkan Shapefile dan dataframe
Saya bekerja Rdengan dataframe biasa ( df) dan shapefile ( map2), kolom yang sama disebut CD116FP. dfmemiliki 103552 baris sedangkan map2memiliki 444. Saya memuat shapefile dengan cara berikut:
peta2 <- read_sf ("D: /Data/tl_2019_us_cd116.shp")
Tujuan akhir saya adalah menggunakan fungsi mapview()untuk melihat peta yang disertakan map2dengan "intensitas" yang dijelaskan di dfbawah kolom np_scores. Karena itu, saya tidak ingin pengamatan dfyang tidak muncul map2.
Inilah pemikiran dan kegagalan saya:
Jika dua objek ini adalah dataframe biasa, kandidat yang masuk akal akan digunakan
merge()untuk menggabungkan kedua objek, namun jika Anda menerapkan fungsi itu dalam kasus ini, objek yang dihasilkan kehilangan properti spasial danmapviewtidak tahu cara membacanya.Pendekatan lain yang saya gunakan adalah mencoba baris kode ini:
map2m <-data.frame (map2, df [cocok (map2$CD116FP, df$CD116FP),])
Tetapi hasilnya memiliki dimensi yang terlalu besar (jauh lebih besar dari 444 garis) dan karenanya mapviewcrash ketika mencoba memplot peta yang diinginkan.
- Akhirnya, saya menggunakan brute force penuh dan hanya membuat loop untuk menambahkan kolom
npkemap2:
map2$np=10 for (i in c(1:nrow(map2))) { for (j in c(1:nrow(df))) { if (identical(map2$CD116FP[i],df$CD116FP[j])) {map2$np[i]=df$np_score[j]} else {map2$np[i]=0}
}
}
Namun, pendekatan ini hanya membutuhkan terlalu banyak waktu mengingat dimensi kerangka data saya.
Apakah Anda punya saran?
Jawaban
Saya agak bingung dengan struktur data Anda. Anda dfmemiliki lebih dari 100.000 baris, jadi saya menebak bahwa hal yang sama CD116FPterjadi beberapa kali df, dan npscorekemauannya mungkin berbeda di semua contoh ini. Jika Anda ingin menggabungkannya, map2Anda harus menggabungkannya terlebih dahulu.
Mari kita coba membuat ulang pengaturan serupa:
library(sf)
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
map2 <- read_sf("C:/users/administrator/documents/shape/tl_2019_us_cd116.shp")
set.seed(69)
df <- data.frame(CD116FP = sprintf("%02d", sample(0:99, 103552, TRUE)),
npscores = runif(103552))
head(df)
#> CD116FP npscores
#> 1 95 0.6927742
#> 2 80 0.8543845
#> 3 90 0.5220353
#> 4 01 0.1449647
#> 5 76 0.9876543
#> 6 38 0.5629950
Saya telah membuat dfjumlah baris yang sama dengan data Anda untuk menunjukkan solusi ini akan menyesuaikan dengan masalah Anda.
Mari kita gabungkan npscoresdengan dplyr:
library(dplyr)
df_sum <- df %>%
filter(CD116FP %in% map2$CD116FP) %>% group_by(CD116FP) %>% summarise(npscores = mean(npscores)) map2$npscores <- df_sum$npscores[match(map2$CD116FP, df_sum$CD116FP)]
Sekarang map2telah agregat yang npscoresdapat kita plot - misalnya, di ggplot:
library(ggplot2)
ggplot(map2) +
geom_sf(aes(fill = npscores)) +
coord_sf(xlim = c(-180, -60),
ylim = c(15, 70)) +
scale_fill_gradient(low = "red", high = "gold")
Atau dalam tampilan peta:
library(mapview)
mapView(map2, zcol = "npscores")
Saya beruntung menggunakan paket biasa mergedari paket dasar. Ini kutipan dari karya saya sendiri jika ini berharga bagi Anda :-)
my_data <- read_excel("TraderDataRaw.xlsx",
sheet = "fsa",
col_types= c("text","text","text","logical","numeric","numeric")) %>%
mutate(resp_rate=mailed/responses)
my_map <- st_read("lfsa000b16a_e.shp", stringsAsFactors = FALSE)
my_merged_data <- merge(my_map, my_data,
by.x=c("CFSAUID","PRUID","PRNAME"),
by.y=c("CFSAUID","PRUID","PRNAME"))