计算第一个非零之前的行数

时间:2018-10-16 17:18:55

标签: r group-by dplyr

我想计算每个物种x日期之前(包括第一个非零)的行数。我已经设法导入和排序数据,并且可以返回每个站点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日期)的值的代码:

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”在第一次调查期间记录了重点物种,而地点“ 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 :(得分:2)

使用:

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

答案 1 :(得分:0)

比Jaap更加冗长。首先,我定义一个计算前导零并加一个的函数。它使用rle(行程编码)功能。

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

答案 2 :(得分:0)

另一种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))