R 使用complete()时添加不需要的值
大家新年快乐 我在将隐式缺失数据转换为显式缺失数据时遇到问题。我总结了在特定调查地点观察到的鸟类数量。这些地点每月调查一次,为期12个月。不幸的是,收集的数据只包含对鸟类的实际观察信息,而没有记录在一个地点没有观察到任何鸟类。当我试图添加缺失的数据时,额外的观察结果被添加到数据中 我的解决方案是使用complete()来填写缺失的数据(即,现场/月份调查没有观察到鸟类)。我能够填写缺失的网站没有问题。然而,当我试着填写缺失的月份时,这些额外的观察结果被添加到那些确实记录了鸟类观察结果的站点上。具体而言,3月(1->2只鸟)和4月(1->2只鸟)的额外观测结果被添加到9号站,因此总共观测到32只鸟,而不是30只鸟 下面是一个示例数据集,以及我正在使用的代码。我已在代码中的何处标记问题。我是tidyverse的新手,所以如果你对如何改进我的代码有什么建议,我洗耳恭听。提前感谢你的帮助。为了以防万一,我还附上了一份正确数量的观察结果R 使用complete()时添加不需要的值,r,tidyr,R,Tidyr,大家新年快乐 我在将隐式缺失数据转换为显式缺失数据时遇到问题。我总结了在特定调查地点观察到的鸟类数量。这些地点每月调查一次,为期12个月。不幸的是,收集的数据只包含对鸟类的实际观察信息,而没有记录在一个地点没有观察到任何鸟类。当我试图添加缺失的数据时,额外的观察结果被添加到数据中 我的解决方案是使用complete()来填写缺失的数据(即,现场/月份调查没有观察到鸟类)。我能够填写缺失的网站没有问题。然而,当我试着填写缺失的月份时,这些额外的观察结果被添加到那些确实记录了鸟类观察结果的站点上。具
libary(tidyverse)
图书馆(lubridate)
图书馆(看门人)
#创建可编辑的
ea%#将站点转换为因子
在(变量(日期),mdy)%>%处更改#转换为日期
突变(年=年(日期))%>%#退出年
变异(月=月(日期,标签=真))%>%#拉出月
mutate(date_ym=make_date(year,month))%>%#由于在Lubridate中还没有ym(),请创建一个新日期,将单个月的所有观测值放在同一天。
分组依据(日期,地点=地点)%>%#分组依据地点和月份
#这里的问题:删除此代码会导致观察的准确数量,但只列出观察的月份。
完成(日期=序号(制造日期(2013年3月)、制造日期(2014年3月)by=“month”)、填充=列表(indivs=0))%>%\未进行观察时,添加月份
总结(分钟=总和(indivs))%>%#计算观察到的鸟类数量
完整(场地=场地标高)%>%#添加未进行观测的站点
排列(fct_relevel(site,levels_site),.by_group=TRUE)%>%#按数字升序排列
透视图(名称从=日期从=分钟,值从=分钟)%>%透视表
装饰#总计(其中=c(“行”、“列”)#对每行和每列求和
问题在于使用complete
和groupby
作为“date\ym”。此外,作为整理代码的一部分,将对mutate\u 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
这就是你想要实现的吗?我试着简化一下你的代码
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)
库(tidyverse)
图书馆(lubridate)
#创建可编辑的
ea%
mutate(date=mdy(date)%>%floor_date(unit=“months”)#我添加了这个部分-它将字符转换为日期,然后将它们转换为每个月的第一个
#这就是你想要实现的吗?
df%
左联合(ea)%>%
分组人(地点、日期)%>%
总结(indivs=sum(indivs,na.rm=T))%>%
排列(键=日期,值=独立)
@akrun和@Jakub.Novotny都回答了我的问题。akrun在我编写的代码上下文中提供了答案,而Jakub.Novotny提供了一个全新的解决方案 @akrun图片已添加。我是有意的,但我忘了。谢谢@阿克伦修好了。车站是个古老的名字。现在应该可以了。你能检查一下我的解决方案输出吗。我猜你的图像只包括选定的列,对吗?这是一个很好的解决方案,@Jakub.Novotny。这太棒了,我真的很兴奋看到一个与我自己写的完全不同的解决方案。我肯定有点东西要学!很高兴帮助@Matt!这太完美了,@akrun!您能否简单地解释一下发生错误的原因,以及您为帮助解决问题而添加的一些小代码?另外,谢谢你简化了我的部分代码。@Matt谢谢。这不是错误,而是使用grouped
列进行扩展。我从组中删除了该列以更正它
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)