当前位置: 首页 > 知识库问答 >
问题:

对sf对象使用group _ by()% > % summary()% > % mutate()的适当过程

洪高阳
2023-03-14

我正在开发一个用于处理R中的sf对象的工作流处理脚本,sf是对象的简单特征类,它提供了一种在整洁中处理空间数据的方法。但是,我在做标准group_by()%时遇到了严重的困难

实际上,我正试图将较低层次的地理区域按较高层次的地理区域进行分组,并输出汇总变量。然后,我需要在新的summered < code > SF 数据对象中改变一个变量,该对象计算多个变量的和,然后除以另一个变量。对于< code>sf对象,最后一个操作抛出错误“x 'x '必须是数字”,但相同的操作适用于相同数据的数据框(只是没有< code>geography)。我已经验证了对于传递给< code>rowSums函数的所有变量,x都是数字。

下面是完整的reprex。在第一个示例中,您会看到对示例数据的sf版本的操作失败。在第二个示例中,使用as.data.frame()单独()函数之前传递,该过程成功,但这消除了对我的分析至关重要的地理位置。

谢谢大家!

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

创建于 2020-09-21 由 reprex 软件包 (v0.3.0)

共有2个答案

张献
2023-03-14

将city_ID分成两个变量可能有一些原因,但是您没有提供任何线索来说明原因。在第一个答案中我做了分割,但是我在这里忽略了使用那些分割变量。

每当数据包含sf几何列时,该sf几何是粘性的,并且会跟随数据。即使数据被子集。当存在sf几何时,它会导致基本的列或行函数(如sum())的问题。因此,在使用和函数之前必须删除该几何。

在第二个答案中,我使用了答案#1中使用的两个变量。nc 数据为第 8 列子集化

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

可以在以下链接查看输出:

阳长恨
2023-03-14

我对下面的代码行进行了更改。

mutate(dumby_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

可以从此链接查看输出。

 类似资料:
  • 我创建了一个如下数组: 如何获取/过滤该数组,使其仅具有“1”、“2”和“5”元素,如下所示: 最好的方法是什么?

  • 问题内容: 我有一个由对象填充的ArrayList。 我的对象类称为有两个字段; 我想使用该字段过滤列表,为了进行测试,我使用了字符串“ test”。 我用了来自谷歌的番石榴,它可以过滤ArrayList。 这是我尝试的代码: 但是此代码不起作用。 问题答案: 这是正常的:Predicates.containsPattern()在s上操作,您的对象未实现。 您需要编写自己的谓词: 然后使用: 但是

  • 我正在尝试在除lat long以外的任何投影中使用geom_sf()绘制多边形。 我正在使用geom_sf()导入数据集手册页面中的示例: 从latlong转换到epsg: 3857 最后,使用ggplot2进行绘图,定义绘图的CR: 我一直在wgs84(即epsg:4326)中获得一张带有lat长轴的地图。我希望轴以米为单位,因此我需要来绘制投影多边形。我做错了什么?

  • 行为可以在这个小片段中看到(作为全局脚本执行): 该警报在Chrome中产生

  • 我们总是希望对未知事件分类.当它发生时,向其它方法传递一块作为参数的代码是最容易地解决方法,也就是说我们希望像处理数据一样处理代码. 一个新的过程对象可以通过proc创建: ruby> quux = proc { | print "QUUXQUUXQUUX!!!\n" | } #<Proc:0x4017357c> 现在quux指向一个对象,像其它对象一样,它也有可以调用的

  • 我在glassfish服务器上使用Jersey的最新版本(2.13),以及jackson的最新版本(版本.2.4)。我已经编写并注册了一个自定义ObjectMapper,但它似乎只有集合被我的自定义ObjectMapper序列化。 我在这个页面上看到了类似的问题:https://java.net/jira/browse/glassfish-20815,但是这里提供的解决方案对我不起作用。