I have a set of sample plots from a map with polygon features (A, B, and C) and a raster of forest type (Cold, Warm, and Hot).
Plot Polygon Forest
1 A Cold
2 A Cold
3 A Cold
4 A Warm
5 B Cold
6 B Cold
7 C Cold
8 C Warm
9 C Hot
10 C Hot
I want to summarize the proportion of each forest type by polygon and also identify the dominant forest type in each polygon. For example:
Polygon Cold Warm Hot Forest_dominant
A 0.75 0.25 0 Cold
B 1 0 0 Cold
C 0.25 0.25 0.5 Hot
CodePudding user response:
It's a bit convoluted, but perhaps:
library(tidyverse)
df <- structure(list(Plot = 1:10, Polygon = c("A", "A", "A", "A", "B",
"B", "C", "C", "C", "C"), Forest = c("Cold", "Cold", "Cold",
"Warm", "Cold", "Cold", "Cold", "Warm", "Hot", "Hot")), class = "data.frame", row.names = c(NA,
-10L))
df %>%
group_by(Polygon, Forest) %>%
summarise(n = n()) %>%
mutate(n = n / sum(n)) %>%
group_by(Polygon) %>%
arrange(Polygon, -n) %>%
mutate(Forest_dominant = first(Forest)) %>%
pivot_wider(names_from = Forest, values_from = n, values_fill = 0) %>%
relocate(Forest_dominant, .after = last_col())
#> `summarise()` has grouped output by 'Polygon'. You can override using the `.groups` argument.
#> # A tibble: 3 × 5
#> # Groups: Polygon [3]
#> Polygon Cold Warm Hot Forest_dominant
#> <chr> <dbl> <dbl> <dbl> <chr>
#> 1 A 0.75 0.25 0 Cold
#> 2 B 1 0 0 Cold
#> 3 C 0.25 0.25 0.5 Hot
Created on 2021-12-22 by the reprex package (v2.0.1)
CodePudding user response:
We first could calculate the proportion within each group and then pivot_wider
library(dplyr)
library(tidyr)
df %>%
group_by(Polygon, Forest) %>%
summarise(n = n()) %>%
mutate(proportion = n/ sum(n),
Forest_dominant = max(proportion), .keep="unused") %>%
pivot_wider(
names_from = Forest,
values_from = proportion,
values_fill = 0
)
Polygon Forest_dominant Cold Warm Hot
<chr> <chr> <dbl> <dbl> <dbl>
1 A Cold 0.75 0.25 0
2 B Cold 1 0 0
3 C Hot 0.25 0.25 0.5
CodePudding user response:
A base R option
reshape(
unique(
transform(
df,
prop = ave(Forest, Polygon, FUN = function(x) table(x)[x] / length(x)),
Forest_dominant = ave(Forest, Polygon, FUN = function(x) names(which.max(table(x))))
)
),
direction = "wide",
idvar = c("Polygon", "Forest_dominant"),
timevar = "Forest"
)
gives
Polygon Forest_dominant prop.Cold prop.Warm prop.Hot
1 A Cold 0.75 0.25 <NA>
5 B Cold 1 <NA> <NA>
7 C Hot 0.25 0.25 0.5
or a data.table
option
dcast(
setDT(df)[
,
.(cnt = .N), .(Polygon, Forest)
][
,
`:=`(prop = proportions(cnt), Forest_dominant = Forest[which.max(cnt)]),
Polygon
],
Polygon Forest_dominant ~ Forest,
value.var = "prop",
fill = 0
)
gives
Polygon Forest_dominant Cold Hot Warm
1: A Cold 0.75 0.0 0.25
2: B Cold 1.00 0.0 0.00
3: C Hot 0.25 0.5 0.25
Data
> dput(df)
structure(list(Polygon = c("A", "A", "A", "A", "B", "B", "C",
"C", "C", "C"), Forest = c("Cold", "Cold", "Cold", "Warm", "Cold",
"Cold", "Cold", "Warm", "Hot", "Hot")), row.names = c(NA, -10L
), class = "data.frame")
CodePudding user response:
library(dplyr, warn.conflicts = FALSE)
df %>%
group_by(Polygon) %>%
summarise(prop.table(table(Forest)) %>% as.list %>% as_tibble) %>%
mutate(
across(-1, coalesce, 0),
Forest_dominant = across(-1) %>% {names(.)[max.col(.)]}
)
#> # A tibble: 3 × 5
#> Polygon Cold Warm Hot Forest_dominant
#> <chr> <dbl> <dbl> <dbl> <chr>
#> 1 A 0.75 0.25 0 Cold
#> 2 B 1 0 0 Cold
#> 3 C 0.25 0.25 0.5 Hot
Created on 2021-12-21 by the reprex package (v2.0.1)