在 dara 框架列表中查找每月和每年的 NA 值百分比

Find percentage of NA values per month and year in a list of dara frames

我有一个包含 83 个 csv 文件的列表,其中包含三个变量。

我创建了新的日期列,包括月份和年份。

我的列表中的一个数据框如下所示:

> head(estaciones$AeropuertodeBocas_93002)
        Date Tx2m Tn2m   Pr year month day
1 1988-01-01 27.4 23.1 41.3 1988     1   1
2 1988-01-02 29.8 24.0  0.3 1988     1   2
3 1988-01-03 30.4 24.0  0.4 1988     1   3
4 1988-01-04 30.0 24.2  2.4 1988     1   4
5 1988-01-05 29.6 23.2  9.1 1988     1   5
6 1988-01-06 30.0 23.1  5.2 1988     1   6

我想创建一个新文件,其中包含每个变量以及每月和每年的 NA 值百分比。例如 1988 年 6 月:变量“Pr”和数据帧“x”缺失值的 2%。

我试过使用:

na_by_month <- map(estaciones, ~ .x %>%
                 mutate(Month=month(Date), Mis = rowSums(is.na(.))) %>% 
                 group_by(Month) %>% 
                 summarise(Sum=sum(Mis), Percentage=mean(Mis)))

这只是计算整个系列每个月的缺失值百分比,而不是每年。

数据(几个df之一):

df <- structure(list(Date = structure(c(6574, 
6575, 6576, 6577, 6578, 6579), class = "Date"),
Tx2m = c(27.4, 29.8, 30.4, 30, 29.6, 30), 
Tn2m = c(23.1, 24, 24, 24.2, 23.2, 23.1), 
Pr = c(41.3, 0.3, 0.4, 2.4, 9.1, 5.2), 
year = c(1988, 1988, 1988, 1988, 1988, 1988 ), 
month = c(1, 1, 1, 1, 1, 1), day = 1:6), 
row.names = c(NA, 6L), class = "data.frame")

如何创建一个新文件,其中包含列表中每个数据框每月和每年的缺失值百分比?谢谢

df <- structure(list(Date = structure(c(6574, 6575, 6576, 6577, 6578, 6579), class = "Date"),
                     Tx2m = c(27.4, 29.8, 30.4, 30, 29.6, 30), Tn2m = c(23.1, 24, 24, 24.2, 23.2, 23.1),
                     Pr = c(41.3, 0.3, 0.4, 2.4, 9.1, 5.2),
                     year = c(1988, 1988, 1988, 1988, 1988, 1988 ),
                     month = c(1, 1, 1, 1, 1, 1), day = 1:6),
                row.names = c(NA, 6L), class = "data.frame")

nongroup_vars <- setdiff(colnames(df),c('year','month'))
nongroup_vars_mr <- paste0(nongroup_vars,'_missing_ratio')

df %>%
group_by(month,year) %>%
summarise_all(function(x) mean(is.na(x))) %>%
ungroup %>%
rename_with(~nongroup_vars_mr,all_of(nongroup_vars))

它表示每个组的缺失比率。

输出;

# A tibble: 1 × 7
  month  year Date_missing_ratio Tx2m_missing_ratio Tn2m_missing_ratio Pr_missing_ratio day_missing_ratio
  <dbl> <dbl>              <dbl>              <dbl>              <dbl>            <dbl>             <dbl>
1     1  1988                  0                  0                  0                0                 0

如果你想通过 month/year 计算缺失值的百分比,你可以编写一个函数,然后你可以映射到你的列表数据帧:

library(dplyr)
library(purrr)
library(openxlsx)
library(rlang)

ldf <- list(df, df, df)

f <- function(data, ...){
  v <- enquos(...)
  data %>%
    group_by(!!! v) %>%
    summarize(across(Tx2m:Pr,
                     list(missing = ~ mean(is.na(.))),
                     .names = paste0("{.col}_{.fn}_", quo_name(v[[1]]))),
              .groups = "drop")
}

miss <- imap(ldf, ~ left_join(f(.x, month, year), f(.x, year), by = "year"))

write.xlsx(miss, "output.xlsx")

工作原理

  1. 您提供函数 f 您的数据框和您想要分组的变量,它将计算这些分组变量的缺失值百分比。例如,f(df, month, year) 将按 monthyear 对数据进行分组,并计算 Tx2m:Pr.
  2. 范围内每个变量的缺失值百分比
f(df, month, year)
  month  year Tx2m_missing_month Tn2m_missing_month Pr_missing_month
  <int> <int>              <dbl>              <dbl>            <dbl>
1     1  1988                  0                  0                0
f(df, year)
   year Tx2m_missing_year Tn2m_missing_year Pr_missing_year
  <int>             <dbl>             <dbl>           <dbl>
1  1988                 0                 0               0

注意:分组变量的顺序在这里很重要。第一个 group by variable 用于构造输出变量名称(例如 Tn2m_missing_month)。

  1. 如果您想要列表中每个元素的 month/year 和年份的缺失数量,那么我们可以使用 imap 应用此函数并通过 year 合并结果.
left_join(f(df, month, year), f(df, year), by = "year")
 month  year Tx2m_missing_month Tn2m_missing_month Pr_missing_month
  <int> <int>              <dbl>              <dbl>            <dbl>
1     1  1988                  0                  0                0
# ... with 3 more variables: Tx2m_missing_year <dbl>,
#   Tn2m_missing_year <dbl>, Pr_missing_year <dbl>

注意:年内的每个月都会重复缺失。

  1. 最后,write.xlsx 会将数据帧列表写入 Excel 工作簿,其中每个 sheet 都是列表的一个元素。

如果我误解了你的 post 而你只想要年内按月计算的缺失百分比,那么你可以将其简化为:

miss <- imap(ldf, ~ f(.x, month, year))

情节

要绘制你可以这样做:

library(ggplot2)
library(tidyr)
library(scales)
library(lubridate)

plots <- imap(miss, ~ .x %>% 
       select(ends_with("year")) %>% 
       distinct() %>% 
       pivot_longer(cols = -year,
                    names_pattern = "(.*?)_(.*)",
                    names_to = c("var", NA)) %>%
       mutate(date = ymd(year, truncated = 2L)) %>% 
       ggplot(aes(x = date, y = value, color = var, group = var)) + 
       geom_point() + 
       geom_line() +
       scale_y_continuous(labels = percent_format()) +
       scale_x_date(date_breaks = "1 year", 
                    date_labels = "%Y")
)

plots[[1]]

其中每个变量是一条线,它的 y 轴值是缺失百分比,x 轴是年份。

注意:对于示例中给定的数据,图形不是那么有趣,并且给出了关于只有一个点的警告。此外,所有点都与给定数据在同一 (x,y) 坐标上重叠。