4

我正在R使用常规数据框 ( df) 和 shapefile ( map2),它们共享一个名为CD116FP. df有 103552 行,而map2有 444 行。我正在通过以下方式加载 shapefile:

map2 <- read_sf("D:/Data/tl_2019_us_cd116.shp")

我的最终目标是使用该功能mapview()来查看包含在列下map2描述的“强度”的地图。因此,我不希望观察结果不会出现在.dfnp_scoresdfmap2

以下是我的想法和失败:

  1. 如果这两个对象是常规数据帧,一个合理的候选者将merge()用于组合这两个对象,但是如果在这种情况下应用该函数,则生成的对象会失去空间属性并且mapview不知道如何读取它。

  2. 我使用的另一种方法是尝试这行代码:

map2m<-data.frame(map2, df[匹配(map2$CD116FP, df$CD116FP),])

但是结果的尺寸太大(比 444 行大得多),因此mapview在尝试绘制所需的地图时会崩溃。

  1. 最后,我全力以赴,只是构建了一个循环来将列添加npmap2
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}  
}
}  

但是,考虑到我的数据框的尺寸,这种方法只需要太多时间。

你有什么建议吗?

4

2 回答 2

3

我对你的数据结构有点困惑。您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您的数据具有相同数量的行,以显示此解决方案将扩展到您的问题。

让我们汇总npscoreswith 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")

或在地图视图中:

library(mapview)
mapView(map2, zcol = "npscores")

在此处输入图像描述 reprex 包(v0.3.0)于 2020-09-19 创建

于 2020-09-19T22:24:29.803 回答
0

我有一些运气使用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"))
于 2020-09-25T17:24:28.727 回答