Подсчитать количество строк перед первым ненулевым - PullRequest
0 голосов
/ 16 октября 2018

Я хочу посчитать количество строк до и включая первое ненулевое значение для каждого вида x даты.Мне удалось импортировать и отсортировать данные, и я могу вернуть значение первой ненулевой строки на сайт x дата, но я не могу вычислить количество строк до первого ненулевого значения.Экологически, этот анализ пытается определить, сколько обследований нужно сделать (вид х дата), чтобы зафиксировать наши основные виды (значения).

Я пытался использовать для этого среду tidyverse / dplyr, пробуя summarise() и n(), но без особого успеха.Любые указатели будут оценены.

Ниже приведен пример данных, для которых я пытался написать этот код:

test_df <- structure(list(site = c("a", "a", "a", "a", "a", "a", 
                               "b", "b", "b", "b", "b", "b", 
                               "c", "c", "c", "c", "c", "c"), 
                      Date = structure(c(17167, 17198, 17226, 17257, 17287, 
                                         17318, 17167, 17198, 17226, 17257, 
                                         17287, 17318, 17167, 17198, 
                                         17226, 17257, 17287, 17318), 
                                       class = "Date"), values = c(0,                                                                                                                        0, 0, 3, 4, 5, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 45, 50)), 
                 row.names = c(NA, -18L), class = "data.frame", 
                 .Names = c("site", "Date", "values"))

Этот код возвращает значение первой ненулевой строки (по видамx date):

test_df %>% 
  # Convert site to factor, so we can use complete later. 
  # We do this within group_by, because we want to operate by level of site
  group_by(site=factor(site)) %>% 
  # Remove all rows of variable if there aren't any rows with values==0
  filter(any(values==0)) %>% 
  # Remove all rows with values != 0
  filter(values != 0) %>% 
  # Keep the first row of each variable, after sorting by date
  # This gives us the first non-zero row
  arrange(Date) %>% 
  slice(1) %>% 
  # Use complete to bring back a row for any level of variable that
  # didn't start with any rows with values==0
  ungroup() %>% 
  complete(site)

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

# A tibble: 3 x 3
  site  Date       values
  <fct> <date>      <dbl>
1 a     2017-04-01      3
2 b     NA             NA
3 c     2017-05-01     45

Я хочу, чтобы она возвращала таблицу со значениями, указывающими количество строк до и включая первуюстрока с ненулевым значением, а не значением первого ненулевого значения, как в таблице выше:

Т.е. для сайта 'a' нам пришлось провести опрос 4 месяца (строки), чтобы записать наш основной видвпервые сайт «b» зафиксировал фокусные виды во время 1-го обследования, а сайт «c» зафиксировал фокусные виды в ходе 5-го обследования.

# A tibble: 3 x 3
  site  Date       values
  <fct> <date>      <dbl>
1 a     2017-04-01      4
2 b     2017-01-01      1
3 c     2017-05-01      5

Ответы [ 3 ]

0 голосов
/ 16 октября 2018

Немного более многословно, чем Яап.Сначала я определяю функцию, которая считает начальные нули и добавляет один.Он использует функцию rle (Run Length Encoding).

count0 <- function(x){
  tmp <- rle(x)
  ifelse(!tmp$values[1], tmp$lengths[1] + 1, 1)
}

Здесь я нахожу дату первого ненулевого элемента, затем применяю count0 для подсчета лидирующих нулей.

test_df %>% 
  group_by(site) %>% 
  summarise(Date = Date[(values>0)][1],                          
            values = count0(values))

Это дает требуемый вывод.

# # A tibble: 3 x 3
#   site  Date       values
#   <chr> <date>      <dbl>
# 1 a     2017-04-01      4
# 2 b     2017-01-01      1
# 3 c     2017-05-01      5
0 голосов
/ 16 октября 2018

Другая dplyr возможность:

test_df %>%
  group_by(site) %>%
  mutate(val = ifelse((values != 0 & lag(values, default = 0) == 0) | values == 0, 1, 0)) %>%
  summarise(Date = first(Date[values != 0]),
            values = sum(val))
0 голосов
/ 16 октября 2018

Использование:

test_df %>% 
  group_by(site) %>% 
  mutate(n = row_number()) %>% 
  filter(values != 0) %>% 
  slice(1)

дает:

# A tibble: 3 x 4
# Groups:   site [3]
  site  Date       values     n
  <chr> <date>      <dbl> <int>
1 a     2017-04-01      3     4
2 b     2017-01-01     10     1
3 c     2017-05-01     45     5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...