การรวม Shapefile และ dataframe
ฉันกำลังทำงานในRกับ dataframe ปกติ ( df) และ shapefile ( map2) CD116FPหุ้นคอลัมน์ทั่วไปเรียกว่า dfมี 103552 บรรทัดในขณะที่map2มี 444 ฉันกำลังโหลด shapefile ด้วยวิธีต่อไปนี้:
map2 <- read_sf ("D: /Data/tl_2019_us_cd116.shp")
สิ้นเป้าหมายของฉันคือการใช้ฟังก์ชั่นmapview()ในการดูแผนที่ที่รวมอยู่ในmap2กับ "ความรุนแรง" ที่อธิบายไว้ในคอลัมน์df np_scoresผมจึงไม่ต้องการให้ข้อสังเกตของที่ไม่ปรากฏในdfmap2
นี่คือความคิดและความล้มเหลวของฉัน:
หากวัตถุทั้งสองนี้เป็นดาต้าเฟรมปกติตัวเลือกที่สมเหตุสมผลจะถูกใช้
merge()เพื่อรวมวัตถุทั้งสองอย่างไรก็ตามหากคุณใช้ฟังก์ชันนั้นในกรณีนี้วัตถุที่ได้รับจะสูญเสียคุณสมบัติเชิงพื้นที่และmapviewไม่รู้ว่าจะอ่านอย่างไรอีกวิธีหนึ่งที่ฉันใช้คือลองใช้โค้ดบรรทัดนี้:
map2m <-data.frame (map2, df [match (map2$CD116FP, df$CD116FP),])
แต่ผลลัพธ์มีขนาดที่ใหญ่เกินไป (ใหญ่กว่า 444 บรรทัด) และmapviewเกิดปัญหาเมื่อพยายามที่จะพล็อตแผนที่ที่ต้องการ
- ในที่สุดฉันก็ใช้กำลังดุร้ายเต็มรูปแบบและเพิ่งสร้างลูปเพื่อเพิ่มคอลัมน์
npไปที่map2:
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}
}
}
อย่างไรก็ตามวิธีนี้ใช้เวลามากเกินไปเนื่องจากขนาดของดาต้าเฟรมของฉัน
คุณมีข้อเสนอแนะใด?
คำตอบ
ฉันงงกับโครงสร้างข้อมูลของคุณเล็กน้อย ของคุณdfมีมากกว่า 100,000 แถวดังนั้นฉันคาดเดาว่าเหตุการณ์เดียวกันCD116FPนี้จะเกิดขึ้นหลายครั้งdfและnpscoreน่าจะแตกต่างกันไปตามอินสแตนซ์เหล่านี้ หากคุณต้องการรวมสิ่งเหล่านี้เข้ากับmap2คุณจะต้องรวมเข้าด้วยกันก่อน
ลองสร้างการตั้งค่าที่คล้ายกันใหม่:
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
ฉันได้ทำให้dfมีจำนวนแถวเดียวกันกับที่ข้อมูลของคุณต้องแสดงโซลูชันนี้จะปรับขนาดตามปัญหาของคุณ
มารวมnpscoresกับ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)]
ตอนนี้map2มีการรวมที่npscoresเราสามารถพล็อต - ตัวอย่างเช่นใน 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")
หรือใน mapview:
library(mapview)
mapView(map2, zcol = "npscores")
ฉันมีโชคบางอย่างที่ใช้แบบเก่าmergeจากแพ็คเกจพื้นฐาน นี่คือข้อความที่ตัดตอนมาจากงานของฉันเองสิ่งนี้ควรมีค่าสำหรับคุณ :-)
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"))