使用 group_by() %>% summarize() %>% mutate() 与 sf 对象的适当程序
Appropriate procedure for using group_by() %>% summarize() %>% mutate() with sf objects
我正在开发一个用于处理 R 中 sf
对象的工作流处理脚本。sf
是对象的简单特征 class,它提供了一种处理空间数据的方法整洁的宇宙。但是,我在执行标准 group_by() %>% summarize() %>% mutate() 处理并将数据存储为 sf
时遇到了严重困难。我遇到一个问题,其中 group_by() %>% summarize() 在对象转换为数据框后与对象一起使用,但不是作为 sf
.
本质上,我是在尝试按较高级别的地理位置对较低级别的地理位置进行分组,并输出汇总变量。然后,我需要在我的新汇总 sf
数据对象中改变一个变量,该对象计算多个变量的总和并除以另一个变量。对于 sf
对象,最后一个操作会抛出错误“x 'x' 必须是数字”,但相同的操作适用于相同数据的数据帧(只是没有 geography
)。我已经验证 x 是 传递给 rowSums
函数的所有变量的数字。
下面是完整的代表。在第一个示例中,您看到在示例数据的 sf
版本上操作失败。在第二个示例中,as.data.frame()
在 separate()
函数之前传递,过程成功,但这消除了对我的分析至关重要的地理位置。
谢谢大家!
library(sf)
#> Warning: package 'sf' was built under R version 4.0.2
#> Linking to GEOS 3.8.1, GDAL 3.1.1, PROJ 6.3.1
library(tidyverse)
#> Warning: package 'ggplot2' was built under R version 4.0.2
#> Warning: package 'tibble' was built under R version 4.0.2
#> Warning: package 'tidyr' was built under R version 4.0.2
#> Warning: package 'dplyr' was built under R version 4.0.2
library(dplyr)
library(spdep)
#> Loading required package: sp
#> Loading required package: spData
#> To access larger datasets in this package, install the spDataLarge
#> package with: `install.packages('spDataLarge',
#> repos='https://nowosad.github.io/drat/', type='source')`
library(stringi)
#> Warning: package 'stringi' was built under R version 4.0.2
nc <- st_read(system.file("shapes/sids.shp", package="spData")[1], quiet=TRUE)
st_crs(nc) <- "+proj=longlat +datum=NAD27"
row.names(nc) <- as.character(nc$FIPSNO)
names(nc)
#> [1] "CNTY_ID" "AREA" "PERIMETER" "CNTY_" "NAME" "FIPS"
#> [7] "FIPSNO" "CRESS_ID" "BIR74" "SID74" "NWBIR74" "BIR79"
#> [13] "SID79" "NWBIR79" "east" "north" "x" "y"
#> [19] "lon" "lat" "L_id" "M_id" "geometry"
nc %>%
separate(CNTY_ID,into = c("ID1","ID2"),sep = 2,remove = FALSE) %>%
group_by(ID1) %>%
dplyr::summarize(AREA = sum(AREA, na.rm = TRUE),
BIR74 = sum(BIR74,na.rm = TRUE),
SID74 = sum(SID74,na.rm = TRUE),
NWBIR74 = sum(NWBIR74,na.rm = TRUE)
) %>%
mutate(stupid_var = rowSums(dplyr::select(.,'SID74':'NWBIR74'))/BIR74)
#> `summarise()` ungrouping output (override with `.groups` argument)
#> Error: Problem with `mutate()` input `stupid_var`.
#> x 'x' must be numeric
#> ℹ Input `stupid_var` is `rowSums(dplyr::select(., "SID74":"NWBIR74"))/BIR74`.
class(nc$SID74)
#> [1] "numeric"
class(nc$NWBIR74)
#> [1] "numeric"
class(nc$BIR74)
#> [1] "numeric"
nc %>%
as.data.frame() %>%
separate(CNTY_ID,into = c("ID1","ID2"),sep = 2,remove = FALSE) %>%
group_by(ID1) %>%
dplyr::summarize(AREA = sum(AREA, na.rm = TRUE),
BIR74 = sum(BIR74,na.rm = TRUE),
SID74 = sum(SID74,na.rm = TRUE),
NWBIR74 = sum(NWBIR74,na.rm = TRUE)
) %>%
mutate(stupid_var = rowSums(dplyr::select(.,'SID74':'NWBIR74'))/BIR74)
#> `summarise()` ungrouping output (override with `.groups` argument)
#> # A tibble: 5 x 6
#> ID1 AREA BIR74 SID74 NWBIR74 stupid_var
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 18 2.53 36723 89 12788 0.351
#> 2 19 4.03 132525 203 38392 0.291
#> 3 20 3.94 111540 237 35281 0.318
#> 4 21 1.63 38117 106 14915 0.394
#> 5 22 0.494 11057 32 3723 0.340
由 reprex package (v0.3.0)
于 2020-09-21 创建
我更改了以下代码行。
mutate(stupid_var = rowSums(dplyr::select(.,'SID74':'NWBIR74'))/BIR74)
这行代码可能导致了问题。除非我遗漏了什么,否则似乎没有理由对每一行的整个列求和。所以代码被更改为删除 rowSums() 函数。 mutate 函数仍用于对每行数据执行数学运算,但不涉及任何 rowSums() 值。
p1 <- nc %>%
separate(CNTY_ID,into = c("ID1","ID2"),sep = 2,remove = FALSE) %>%
group_by(ID1) %>%
dplyr::summarize(AREA = sum(AREA, na.rm = TRUE),
BIR74 = sum(BIR74,na.rm = TRUE),
SID74 = sum(SID74,na.rm = TRUE),
NWBIR74 = sum(NWBIR74,na.rm = TRUE)) %>%
mutate( stupid_var = ( (p2$SID74) + (p2$NWBIR74)) / (p2$BIR74) )
p1
可以从这里查看输出link.
city_ID 被分成 2 个变量可能有一些原因,但您没有提供任何线索来说明原因。在第一个答案中,我进行了拆分,但我在这里忽略了使用那些拆分变量。
每当数据包含 sf 几何列时,该 sf 几何就会粘附在数据之后。即使数据被子集化。当存在 sf 几何时,它会导致基本列或行函数(如 sum())出现问题。因此必须在使用求和函数之前删除该几何图形。
在第二个答案中,我使用了与答案 # 1 中相同的两个变量。nc 数据对第 8 列和第 9 列进行了子集化。我的选择是因为没有关于将哪些列加在一起的指导。然后删除 sf 几何图形,然后使用 rowSums 函数为每一行添加每一列的值。
gr_1 <- nc[, c(9:10)]
gr_1 <- st_drop_geometry(gr_1)
rownames(gr_1) = NULL # to remove extraneous data from gr_1
xsum <- c(rowSums(gr_1))
head(xsum) # displays values of xsum
可以在此处查看输出 link:
我正在开发一个用于处理 R 中 sf
对象的工作流处理脚本。sf
是对象的简单特征 class,它提供了一种处理空间数据的方法整洁的宇宙。但是,我在执行标准 group_by() %>% summarize() %>% mutate() 处理并将数据存储为 sf
时遇到了严重困难。我遇到一个问题,其中 group_by() %>% summarize() 在对象转换为数据框后与对象一起使用,但不是作为 sf
.
本质上,我是在尝试按较高级别的地理位置对较低级别的地理位置进行分组,并输出汇总变量。然后,我需要在我的新汇总 sf
数据对象中改变一个变量,该对象计算多个变量的总和并除以另一个变量。对于 sf
对象,最后一个操作会抛出错误“x 'x' 必须是数字”,但相同的操作适用于相同数据的数据帧(只是没有 geography
)。我已经验证 x 是 传递给 rowSums
函数的所有变量的数字。
下面是完整的代表。在第一个示例中,您看到在示例数据的 sf
版本上操作失败。在第二个示例中,as.data.frame()
在 separate()
函数之前传递,过程成功,但这消除了对我的分析至关重要的地理位置。
谢谢大家!
library(sf)
#> Warning: package 'sf' was built under R version 4.0.2
#> Linking to GEOS 3.8.1, GDAL 3.1.1, PROJ 6.3.1
library(tidyverse)
#> Warning: package 'ggplot2' was built under R version 4.0.2
#> Warning: package 'tibble' was built under R version 4.0.2
#> Warning: package 'tidyr' was built under R version 4.0.2
#> Warning: package 'dplyr' was built under R version 4.0.2
library(dplyr)
library(spdep)
#> Loading required package: sp
#> Loading required package: spData
#> To access larger datasets in this package, install the spDataLarge
#> package with: `install.packages('spDataLarge',
#> repos='https://nowosad.github.io/drat/', type='source')`
library(stringi)
#> Warning: package 'stringi' was built under R version 4.0.2
nc <- st_read(system.file("shapes/sids.shp", package="spData")[1], quiet=TRUE)
st_crs(nc) <- "+proj=longlat +datum=NAD27"
row.names(nc) <- as.character(nc$FIPSNO)
names(nc)
#> [1] "CNTY_ID" "AREA" "PERIMETER" "CNTY_" "NAME" "FIPS"
#> [7] "FIPSNO" "CRESS_ID" "BIR74" "SID74" "NWBIR74" "BIR79"
#> [13] "SID79" "NWBIR79" "east" "north" "x" "y"
#> [19] "lon" "lat" "L_id" "M_id" "geometry"
nc %>%
separate(CNTY_ID,into = c("ID1","ID2"),sep = 2,remove = FALSE) %>%
group_by(ID1) %>%
dplyr::summarize(AREA = sum(AREA, na.rm = TRUE),
BIR74 = sum(BIR74,na.rm = TRUE),
SID74 = sum(SID74,na.rm = TRUE),
NWBIR74 = sum(NWBIR74,na.rm = TRUE)
) %>%
mutate(stupid_var = rowSums(dplyr::select(.,'SID74':'NWBIR74'))/BIR74)
#> `summarise()` ungrouping output (override with `.groups` argument)
#> Error: Problem with `mutate()` input `stupid_var`.
#> x 'x' must be numeric
#> ℹ Input `stupid_var` is `rowSums(dplyr::select(., "SID74":"NWBIR74"))/BIR74`.
class(nc$SID74)
#> [1] "numeric"
class(nc$NWBIR74)
#> [1] "numeric"
class(nc$BIR74)
#> [1] "numeric"
nc %>%
as.data.frame() %>%
separate(CNTY_ID,into = c("ID1","ID2"),sep = 2,remove = FALSE) %>%
group_by(ID1) %>%
dplyr::summarize(AREA = sum(AREA, na.rm = TRUE),
BIR74 = sum(BIR74,na.rm = TRUE),
SID74 = sum(SID74,na.rm = TRUE),
NWBIR74 = sum(NWBIR74,na.rm = TRUE)
) %>%
mutate(stupid_var = rowSums(dplyr::select(.,'SID74':'NWBIR74'))/BIR74)
#> `summarise()` ungrouping output (override with `.groups` argument)
#> # A tibble: 5 x 6
#> ID1 AREA BIR74 SID74 NWBIR74 stupid_var
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 18 2.53 36723 89 12788 0.351
#> 2 19 4.03 132525 203 38392 0.291
#> 3 20 3.94 111540 237 35281 0.318
#> 4 21 1.63 38117 106 14915 0.394
#> 5 22 0.494 11057 32 3723 0.340
由 reprex package (v0.3.0)
于 2020-09-21 创建
我更改了以下代码行。
mutate(stupid_var = rowSums(dplyr::select(.,'SID74':'NWBIR74'))/BIR74)
这行代码可能导致了问题。除非我遗漏了什么,否则似乎没有理由对每一行的整个列求和。所以代码被更改为删除 rowSums() 函数。 mutate 函数仍用于对每行数据执行数学运算,但不涉及任何 rowSums() 值。
p1 <- nc %>%
separate(CNTY_ID,into = c("ID1","ID2"),sep = 2,remove = FALSE) %>%
group_by(ID1) %>%
dplyr::summarize(AREA = sum(AREA, na.rm = TRUE),
BIR74 = sum(BIR74,na.rm = TRUE),
SID74 = sum(SID74,na.rm = TRUE),
NWBIR74 = sum(NWBIR74,na.rm = TRUE)) %>%
mutate( stupid_var = ( (p2$SID74) + (p2$NWBIR74)) / (p2$BIR74) )
p1
可以从这里查看输出link.
city_ID 被分成 2 个变量可能有一些原因,但您没有提供任何线索来说明原因。在第一个答案中,我进行了拆分,但我在这里忽略了使用那些拆分变量。
每当数据包含 sf 几何列时,该 sf 几何就会粘附在数据之后。即使数据被子集化。当存在 sf 几何时,它会导致基本列或行函数(如 sum())出现问题。因此必须在使用求和函数之前删除该几何图形。
在第二个答案中,我使用了与答案 # 1 中相同的两个变量。nc 数据对第 8 列和第 9 列进行了子集化。我的选择是因为没有关于将哪些列加在一起的指导。然后删除 sf 几何图形,然后使用 rowSums 函数为每一行添加每一列的值。
gr_1 <- nc[, c(9:10)]
gr_1 <- st_drop_geometry(gr_1)
rownames(gr_1) = NULL # to remove extraneous data from gr_1
xsum <- c(rowSums(gr_1))
head(xsum) # displays values of xsum
可以在此处查看输出 link: