【问题标题】:Find percentage of NA values per month and year in a list of dara frames在数据框列表中查找每月和每年的 NA 值百分比
【发布时间】:2021-11-08 21:30:15
【问题描述】:

我有一个包含 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)))

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

数据(几个 dfs 之一):

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")

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

【问题讨论】:

  • 请提供数据:dput(head(estaciones$AeropuertodeBocas_93002))

标签: r list dataframe na


【解决方案1】:

如果您尝试按月/年仅按年计算缺失值的百分比,您可以编写一个函数,然后将其映射到您的数据框列表:

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 范围内每个变量的缺失值百分比。
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

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

  1. 如果您想要列表中每个元素按月/年和按年的缺失数,那么我们可以使用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 工作簿,其中每个工作表都将成为列表的一个元素。

如果我误解了您的帖子,而您只希望一年中按月丢失的百分比,那么您可以将其简化为:

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) 坐标上重叠。

【讨论】:

  • 谢谢,这对计算我需要的东西很有用。你知道我可以用什么方法来想象这个吗?尤其是每个数据框每年缺失值的百分比?
  • @Adi 不客气。我已经更新了我的答案以包括绘图代码。希望对您有所帮助。
【解决方案2】:
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

【讨论】:

    猜你喜欢
    • 2021-08-17
    • 1970-01-01
    • 2023-03-09
    • 2021-01-10
    • 2021-03-08
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多