Расчет скорости изменения между минимальным и максимальным годами в подгруппе - PullRequest
2 голосов
/ 19 сентября 2019

Я относительно новичок в R и прошу прощения, если вопрос уже задавался, но я, очевидно, либо не могу понять ответы, либо не могу найти правильные ключевые слова!

Вот моя проблема: у меня естьнабор данных, который выглядит следующим образом:

   Name           Year  Corg
 1 Bois 17        2001   1.7
 2 Bois 17        2007   2.1
 3 Bois 17        2014   1.9
 4 8-Toume        2000   1.7
 5 8-Toume        2015   1.4
 6 7-Richelien 2  2004   1.1
 7 7-Richelien 2  2017   1.5
 8 7-Richelien 2  2019   1.2
 9  Communaux     2003   1.4
 10 Communaux     2016   3.8
 11 Communaux     2019   2.4
 12 Cocandes      2000   1.7
 13 Cocandes      2014   2.1

Как вы можете видеть, у меня иногда есть две или три строки результатов на имя (теоретически у меня может быть даже 4, 5 или более строк на имя).

Для каждого имени я хотел бы рассчитать годовой коэффициент изменения Corg между самым высоким годом и самым низким годом.

Более конкретно, я хотел бы сделать:

(Corg_of_highest_year/Corg_of_lowest_year)^(1/(lowest_year-highest_year))-1

Не могли бы вы объяснить, как вы получите сводный набор данных, который будет выглядеть так:

Name      Length_in_years   Corg_rate
Bois 17   13                0.9%
8-Toume   15                -1.3%
etc.

Ответы [ 4 ]

1 голос
/ 19 сентября 2019

Мы можем сделать расчет, используя group_by в dplyr

library(dplyr)

df %>%
  group_by(Name) %>%
  summarise(Length = diff(range(Year)), 
        Corg_rate = ((Corg[which.max(Year)]/Corg[which.min(Year)]) ^ 
                      (1/Length) - 1) * 100)

# A tibble: 5 x 3
#  Name         Length Corg_rate
#  <fct>         <int>     <dbl>
#1 7-Richelien2     15     0.582
#2 8-Toume          15    -1.29 
#3 Bois17           13     0.859
#4 Cocandes         14     1.52 
#5 Communaux        16     3.43 

Чтобы выполнить анализ с самым последним годом и годом с минимальной разницей в 5 лет

df %>%
  group_by(Name) %>%  
  summarise(Length = max(Year) - max(Year[Year <= max(Year) - 5]),
            Corg_rate = (Corg[which.max(Year)]/Corg[Year == max(Year[Year <= (max(Year) - 5)])]) ^ (1/Length) - 1, 
            Corg_rate = Corg_rate * 100)



# Name         Length Corg_rate
#  <fct>         <int>     <dbl>
#1 7-Richelien2     15     0.582
#2 8-Toume          15    -1.29 
#3 Bois17            7    -1.42  
#4 Cocandes         14     1.52 
#5 Communaux        16     3.43 

данные

df <- structure(list(Name = structure(c(3L, 3L, 3L, 2L, 2L, 1L, 1L, 
1L, 5L, 5L, 5L, 4L, 4L), .Label = c("7-Richelien2", "8-Toume", 
"Bois17", "Cocandes", "Communaux"), class = "factor"), Year = c(2001L, 
2007L, 2014L, 2000L, 2015L, 2004L, 2017L, 2019L, 2003L, 2016L, 
2019L, 2000L, 2014L), Corg = c(1.7, 2.1, 1.9, 1.7, 1.4, 1.1, 
1.5, 1.2, 1.4, 3.8, 2.4, 1.7, 2.1)), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"))
1 голос
/ 19 сентября 2019

Сначала создав индикатор того, когда год является максимальным и минимальным в имени группы, а затем распространив столбец Corg на MAX_Corg (Corg максимального года) и MIN_corg, мы позже можем легко рассчитать скорость изменения.

my_df %>% 
  group_by(Name) %>%
  mutate( #new column denoting the max and min
    year_max_min = ifelse(Year == max(Year), "MAX_corg",
                          ifelse(Year == min(Year), "MIN_corg",
                                 NA
                                 ) 
                          ) 
  ) %>% 
  filter(!(is.na(year_max_min))) %>% # removing NA
  group_by(Name,  year_max_min) %>%  #grouping by Name and max_min indicator
  summarise(Corg= Corg) %>% #summarising
  spread(year_max_min, Corg) %>% #spread the indicator into two column; MAX_corg and MIN_corg
  mutate(
    rate_of_change = (MAX_corg / MIN_corg)^(1/(MIN_corg - MAX_corg)) - 1 # calculates rate of change
    )

0 голосов
/ 24 сентября 2019

Вот решение с использованием data.table:

df = data.table(df)

mat = df[, .(
   Rate = 100*((Corg[which.max(Year)] / Corg[which.min(Year)])^(1/diff(range(Year))) - 1)
), by = Name]

> mat
           Name       Rate
1:       Bois17  0.8592524
2:      8-Toume -1.2860324
3: 7-Richelien2  0.5817615
4:    Communaux  3.4261123
5:     Cocandes  1.5207989
0 голосов
/ 19 сентября 2019

Используйте dplyr group_by (имя), а затем рассчитайте свое значение.Вот пример

library(dplyr)

data %>%
group_by(name) %>%
summarise(Length = max(Year)-min(Year), Corg_End = sum(Corg[Year==max(Year), Corg_Start = sum(Corg[Year==min(Year)]))

Здесь показана логика группировки, т.е. после group_by (имя) max(Year) выдаст наибольший год для имени вместо общего.Используя эту логику, вычисление скорости изменения должно быть простым, но я не буду пытаться из-за отсутствия воспроизводимых данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...