R: Написание функции, чтобы увидеть, монотонно ли увеличивается высота растения - PullRequest
1 голос
/ 25 марта 2020

Я пишу функцию, чтобы проверить, соответствует ли высота растений монотонному c росту. Поскольку в данных есть NA, которая не делает недействительным прямое предположение, я бы хотел, чтобы они были заполнены сверху вниз, а если первое значение в серии - NA, это должно быть заполнено снизу вверх. Как мне указать, что я хотел бы, чтобы ряды без записанных высот были оставлены в NA?

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

plantid <- rep(c(1,2,3,4,5), times=c(3,3,3,3,3))
year <- rep(1:3, length.out=length(plantid))
height <- c(1,2,3,1,NA,3,3,2,1,NA,2,3,1,3,2)
plant.df <- data.frame(plantid,year,height)

Однако, когда спрашивается, есть ли Нарушая (уменьшая) тенденцию роста особи растения, мой dplyr отвечает TRUE за все.

plant.df %>% group_by(plantid, year) %>% 
      arrange(plantid, year) %>%
      tidyr::fill(height, direction="downup") %>% 
      mutate(monotonic_growth = all(height==cummax(height)))

Ожидаемый результат:

monotonic_growth<- c(rep(TRUE, 3), rep(TRUE, 3), rep(FALSE, 3), rep(TRUE,3), rep(FALSE,3))
cbind(plant.df,monotonic_growth)

Есть ли способ избежать все (), так что я могу отсортировать более подробно позже? т.е. ожидаемый результат:

monotonic_growth <- c(1,1,1,1,1,1,1,0,0,1,1,1,1,0,0)
cbind(plant.df,monotonic_growth)

Большое спасибо !!

1 Ответ

1 голос
/ 25 марта 2020

Вы перегруппировываетесь. Поскольку у вас есть не более одного наблюдения на plantid и year, tidyr::fill видит только одно значение, а когда NA нечего вменять. Группируйте только по plantid.

plant.df %>%
  group_by(plantid) %>% 
  arrange(plantid, year) %>%
  tidyr::fill(height, .direction="downup") %>%
  mutate(monotonic_growth = all(height==cummax(height))) %>%
  ungroup()
# # A tibble: 15 x 4
#    plantid  year height monotonic_growth
#      <dbl> <int>  <dbl> <lgl>           
#  1       1     1      1 TRUE            
#  2       1     2      2 TRUE            
#  3       1     3      3 TRUE            
#  4       2     1      1 TRUE            
#  5       2     2      1 TRUE            
#  6       2     3      3 TRUE            
#  7       3     1      3 FALSE           
#  8       3     2      2 FALSE           
#  9       3     3      1 FALSE           
# 10       4     1      2 TRUE            
# 11       4     2      2 TRUE            
# 12       4     3      3 TRUE            
# 13       5     1      1 FALSE           
# 14       5     2      3 FALSE           
# 15       5     3      2 FALSE           

Альтернативой вашему all вызову является использование diff. Два варианта:

  1. Если height в этом году больше или равно прошлогоднему:

    plant.df %>%
      group_by(plantid) %>%
      arrange(plantid, year) %>%
      tidyr::fill(height, .direction="downup") %>%
      mutate(monotonic_growth = c(TRUE, diff(height) > 0)) %>%
      ungroup()
    # # A tibble: 15 x 4
    #    plantid  year height monotonic_growth
    #      <dbl> <int>  <dbl> <lgl>           
    #  1       1     1      1 TRUE            
    #  2       1     2      2 TRUE            
    #  3       1     3      3 TRUE            
    #  4       2     1      1 TRUE            
    #  5       2     2      1 FALSE           
    #  6       2     3      3 TRUE            
    #  7       3     1      3 TRUE            
    #  8       3     2      2 FALSE           
    #  9       3     3      1 FALSE           
    # 10       4     1      2 TRUE            
    # 11       4     2      2 FALSE           
    # 12       4     3      3 TRUE            
    # 13       5     1      1 TRUE            
    # 14       5     2      3 TRUE            
    # 15       5     3      2 FALSE           
    

    Это показывает, где у вас растущий рост.

  2. Вы можете расширить это, чтобы включить однотонный c рост до тех пор, пока не произойдет, с cumall:

    plant.df %>%
      group_by(plantid) %>%
      arrange(plantid, year) %>%
      tidyr::fill(height, .direction="downup") %>%
      mutate(monotonic_growth = cumall(c(TRUE, diff(height) > 0))) %>%
      ungroup()
    # # A tibble: 15 x 4
    #    plantid  year height monotonic_growth
    #      <dbl> <int>  <dbl> <lgl>           
    #  1       1     1      1 TRUE            
    #  2       1     2      2 TRUE            
    #  3       1     3      3 TRUE            
    #  4       2     1      1 TRUE            
    #  5       2     2      1 FALSE           
    #  6       2     3      3 FALSE           
    #  7       3     1      3 TRUE            
    #  8       3     2      2 FALSE           
    #  9       3     3      1 FALSE           
    # 10       4     1      2 TRUE            
    # 11       4     2      2 FALSE           
    # 12       4     3      3 FALSE           
    # 13       5     1      1 TRUE            
    # 14       5     2      3 TRUE            
    # 15       5     3      2 FALSE           
    
...