【问题标题】:Unwanted values being added when using complete()使用 complete() 时添加了不需要的值
【发布时间】:2020-01-01 20:15:36
【问题描述】:

大家新年快乐!

我在将隐式缺失数据转换为显式缺失数据时遇到问题。我正在总结特定调查地点的鸟类观察次数。这些网站每月调查一次,为期 12 个月。不幸的是,收集的数据仅包含有关鸟类实际观察的信息,而不是记录在某个地点没有观察到鸟类。当我尝试添加丢失的数据时,额外的观察结果被添加到数据中。

我的解决方案是使用 complete() 来填充缺失的数据(即,现场/月调查未观察到鸟类)。我能够毫无问题地填写缺失的网站。然而,当我尝试填写缺失的月份时,额外的观察结果被添加到确实记录了鸟类观察结果的站点中。具体来说,在 3 月(1 -> 2 只鸟)和 4 月(1 -> 2 只鸟)的第 9 站添加了额外的观察结果,总共观察到 32 只鸟,而不是 30 只鸟。

下面是一个示例数据集,以及我正在使用的代码。我已经在代码中标记了我遇到问题的位置。我是 tidyverse 的新手,所以如果您对如何改进我的代码有任何一般性的建议,我会全力以赴。在此先感谢您的帮助。为了以防万一,我还包括了正确数量的观察结果的照片。

libary(tidyverse)
library(lubridate)
library(janitor)

# Create tibble
ea <- tibble(site = c(9,15,9,10,2,8,8,8,8,8,8,8,8,8,8,8,8,7),
date = c("3/26/2013","3/26/2013","4/10/2013","4/20/2013","5/31/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","1/9/2014"),
indivs = c(1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,1),
within_800 = c(TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE))

# Create variable that contains all site names
levels_site <- as.character(1:16)

ea %>%
mutate_at(vars(site), factor) %>% # Convert site into a factor
mutate_at(vars(date), mdy) %>% # convert into a date
mutate(year = year(date))%>% # Pull out year
mutate(month = month(date, label = TRUE)) %>% # Pull out month
mutate(date_ym = make_date(year, month))%>% # Since ym() is not available in Lubridate yet, make a new date that puts all observations from a single month on the same day.
group_by(date_ym, site = site) %>% # Group bysite and month

# Issue here: Removing this code results in the accurate number of observations but only lists the months with an observation.
complete(date_ym = seq(make_date(2013, 3), make_date(2014, 3), by = "month"),fill = list(indivs = 0)) %>% # Add in months were an observations wasn't made

summarise(minutes = sum(indivs)) %>% # Count the number of birds observed
complete(site = levels_site) %>% # Add in the stations were observations weren't made
arrange(fct_relevel(site, levels_site), .by_group = TRUE) %>% # Place in ascending numeric order
pivot_wider(names_from = date_ym, values_from = minutes) %>% # Pivot table
adorn_totals(where = c("row", "col")) # Sum each row and column

【问题讨论】:

  • @akrun 图片已添加。我的意思是,它让我忘记了。谢谢!
  • @akrun 已修复。车站是一个古老的名字。它现在应该可以工作了。
  • 您能否检查我的解决方案输出。我猜你的图片只包含选定的列,对吧?

标签: r tidyr


【解决方案1】:

问题在于将completegroup_by 一起用于“date_ym”。此外,作为整理代码的一部分,将对mutate_at/mutate 的多次调用更改为单个mutate

library(dplyr)
library(tidyr)
library(janitor)
library(lubridate)
ea %>% 
      mutate(site = factor(site),
             date = mdy(date),
             year = year(date),
             month = month(date, label = TRUE),
            date_ym = make_date(year, month)) %>%
      group_by(site) %>% 
      complete(date_ym = seq(make_date(2013, 3), make_date(2014, 3),
           by = 'month', fill = list(indivs = 0))) %>% 
      group_by(date_ym, add = TRUE) %>%
      summarise(minutes = sum(indivs)) %>%
      ungroup %>%
      complete(site = levels_site) %>% 
      arrange(factor(site, levels = levels_site)) %>% 
      pivot_wider(names_from = date_ym, values_from = minutes) %>% 
      rename(station = site) %>%
      select(-`NA`) %>%
      adorn_totals(where = c("row", "col")) 
#station 2013-03-01 2013-04-01 2013-05-01 2013-06-01 2013-07-01 2013-08-01 2013-09-01 2013-10-01 2013-11-01
#       1         NA         NA         NA         NA         NA         NA         NA         NA         NA
#       2         NA         NA          1         NA         NA         NA         NA         NA         NA
#       3         NA         NA         NA         NA         NA         NA         NA         NA         NA
#       4         NA         NA         NA         NA         NA         NA         NA         NA         NA
#       5         NA         NA         NA         NA         NA         NA         NA         NA         NA
#       6         NA         NA         NA         NA         NA         NA         NA         NA         NA
#       7         NA         NA         NA         NA         NA         NA         NA         NA         NA
#       8         NA         NA         NA         24         NA         NA         NA         NA         NA
#       9          1          1         NA         NA         NA         NA         NA         NA         NA
#      10         NA          1         NA         NA         NA         NA         NA         NA         NA
#      11         NA         NA         NA         NA         NA         NA         NA         NA         NA
#      12         NA         NA         NA         NA         NA         NA         NA         NA         NA
#      13         NA         NA         NA         NA         NA         NA         NA         NA         NA
#      14         NA         NA         NA         NA         NA         NA         NA         NA         NA
#      15          1         NA         NA         NA         NA         NA         NA         NA         NA
#      16         NA         NA         NA         NA         NA         NA         NA         NA         NA
#   Total          2          2          1         24          0          0          0          0          0
# 2013-12-01 2014-01-01 2014-02-01 2014-03-01 Total
#         NA         NA         NA         NA     0
#         NA         NA         NA         NA     1
#         NA         NA         NA         NA     0
#         NA         NA         NA         NA     0
#         NA         NA         NA         NA     0
#        NA         NA         NA         NA     0
#        NA          1         NA         NA     1
#         NA         NA         NA         NA    24
#         NA         NA         NA         NA     2
#         NA         NA         NA         NA     1
#         NA         NA         NA         NA     0
#         NA         NA         NA         NA     0
#         NA         NA         NA         NA     0
#         NA         NA         NA         NA     0
#         NA         NA         NA         NA     1
#         NA         NA         NA         NA     0
#          0          1          0          0    30

【讨论】:

  • 这太完美了,@akrun!您能否简要说明错误发生的原因以及您为帮助解决问题而添加的一些小代码?另外,感谢您简化了我的部分代码。
  • @Matt 谢谢。这不是错误,而是使用grouped 列进行扩展。我从组中删除了该列以更正它
【解决方案2】:

这是您想要完成的任务吗?我试着稍微简化你的代码。

library(tidyverse)
library(lubridate)

# Create tibble
ea <- tibble(site = c(9,15,9,10,2,8,8,8,8,8,8,8,8,8,8,8,8,7),
             date = c("3/26/2013","3/26/2013","4/10/2013","4/20/2013","5/31/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","6/29/2013","1/9/2014"),
             indivs = c(1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,1),
             within_800 = c(TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE)) %>%
  mutate(date = mdy(date) %>% floor_date(unit = "months")) # I have added this part - it turns the characters to date and then transforms them to the first of each month

# Is this what you are tryiing to accomplish?
df <- crossing(site = 1:16, date = seq.Date(from = min(ea$date), to = max(ea$date), by = "months")) %>%
  left_join(ea) %>%
  group_by(site, date) %>%
  summarise(indivs = sum(indivs, na.rm = T)) %>%
  spread(key = date, value = indivs)

【讨论】:

  • 很好的解决方案,@Jakub.Novotny。这太棒了,我很高兴看到一个与我自己写的完全不同的解决方案。我肯定有一点要学!
  • 乐于帮助@Matt!
【解决方案3】:

@akrun 和 @Jakub.Novotny 都为我的问题提供了答案。 akrun 在我编写的代码上下文中提供了答案,而 Jakub.Novotny 提供了一个全新的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 2014-10-14
    • 1970-01-01
    • 1970-01-01
    • 2014-09-24
    • 2012-10-12
    • 1970-01-01
    相关资源
    最近更新 更多