R,增长率,不同时间

R, rate of growth, different time

我有以下生物学项目的数据集示例。 我想计算 1 月 4 日到 1 月 2 日之间的数字增长率。 即速率 = (number_at_0104 - number_at_0102)/(number_at_0102) (如果可能,在 tidyverse 中)

a <- c("Date", "Specie", "Number")
b <- c("2020-01-01", "Dog", "3")
c <- c("2020-01-02", "Dog", "4")
d <- c("2020-01-03", "Dog", "5")
e <- c("2020-01-04", "Dog", "6")
f <- c("2020-01-01", "Cat", "3")
g <- c("2020-01-02", "Cat", "7")
h <- c("2020-01-03", "Cat", "8")
i <- c("2020-01-04", "Cat", "10")

df <- as.data.frame(rbind(b, c, d, e, f, g, h, i))
names(df) <- a
df$Date <- as.Date(df$Date)
df$Number <- as.integer(df$Number)

我想计算一个增长率。我知道这已经被处理过了,但我不确定我是否可以在那里应用它。 通常,我们使用 lag() 函数,但我有一些疑问。

提前谢谢你,

使用 dplyr

start <- as.Date("2020-01-02")
end <- as.Date("2020-01-04")

df %>%
  filter(Date %between% c(start, end)) %>%
  arrange(Date, Species) %>%
  group_by(Species) %>%
  summarise(Growth = (last(Number) - first(Number)) / first(Number))

输出

  Species Growth
  <fct>    <dbl>
1 Cat       0.25
2 Dog       0.5 

数据 请注意,我的测试数据已经是日期和数值

df <- data.frame(
  Date = rep(seq.Date(as.Date("2020-01-01"), as.Date("2020-01-04"), "days"), 2),
  Species = c(rep("Dog", 4), rep("Cat", 4)),
  Number = 3:10
)

如果您想对每个物种进行不同的查找,您可以这样做。定义您的查找,输出将包含物种、生长及其来源的时间。

lookups <- list(
  c("Species" = "Dog", "start" = "2020-01-01", "end" = "2020-01-04"),
  c("Species" = "Cat", "start" = "2020-01-02", "end" = "2020-01-04")
)

bind_rows(lapply(lookups, function(species) {
  df %>%
  filter(Species == species["Species"] & Date %between% as.Date(c(species["start"], species["end"]))) %>%
  arrange(Date, Species) %>%
  group_by(Species) %>%
  summarise(
    Growth = (last(Number) - first(Number)) / first(Number),
    Start = species["start"],
    End = species["end"]
  )
}))


# # A tibble: 2 x 4
#   Species Growth Start      End       
#   <chr>    <dbl> <chr>      <chr>     
# 1 Dog       1    2020-01-01 2020-01-04
# 2 Cat       0.25 2020-01-02 2020-01-04

因为你想为不同的物种和不同的开始和结束日期提供不同的输入,我创建了一个函数来完成这项工作。

函数compute_rate_in_species()

  • x 是一个数据框
  • speciesx 中的物种,可以在向量中提供(例如 c("Dog", "Cat")
  • start_dateend_date 不言自明
  • DF 是一个逻辑值,指示您是否要将数据帧作为输出。如果FALSE,一个命名向量作为输出
  • 如果您想为不同的 species 使用不同的 start_dateend_date,您必须使用所需的输入分别 运行 函数。
library(tidyverse)

compute_rate_in_species <- function(x, species, start_date, end_date, DF = T) {
  x <- x %>% filter(Species %in% species & Date %in% as.Date(c(start_date, end_date))) %>% 
    group_by(Species) %>% 
    summarize(Rate = (last(Number) - first(Number))/first(Number))
  if (DF == T) {
    return(x) 
    } else {
      x_vec <- setNames(x$Rate, x$Species)
      return(x_vec)
  }
}

输出

# DF = F
compute_rate_in_species(df, c("Dog", "Cat"), "2020-01-01", "2020-01-03", DF = F)

      Cat       Dog 
1.6666667 0.6666667 

# DF = T
compute_rate_in_species(df, c("Dog", "Cat"), "2020-01-01", "2020-01-03", DF = T)
# A tibble: 2 x 2
  Species  Rate
  <chr>   <dbl>
1 Cat     1.67 
2 Dog     0.667

你可以使用-

library(dplyr)

start_date <- as.Date("2020-01-02")
end_date <- as.Date("2020-01-04")

df %>%
  group_by(Specie) %>%
  summarise(growth_rate = (Number[match(end_date, Date)] - 
                           Number[match(start_date, Date)])/
                           Number[match(start_date, Date)])

#  Specie growth_rate
#  <chr>        <dbl>
#1 Cat          0.429
#2 Dog          0.5  

您可以将 start_dateend_date 替换为您选择的日期。

或者可能有点冗长但更清晰的答案是 -

df %>%
  group_by(Specie) %>%
  summarise(num_end = Number[match(end_date, Date)], 
            num_start = Number[match(start_date, Date)], 
            growth_rate = (num_end - num_start)/num_start)

#  Specie num_end num_start growth_rate
#  <chr>    <int>     <int>       <dbl>
#1 Cat         10         7       0.429
#2 Dog          6         4       0.5