如何用dplyr统计数据框变量的年度覆盖情况并生成透视表?
用dplyr实现变量年度覆盖情况统计
原始数据
ID Year Var1 Var2 Var3 Var4 1 2001 1 1 3 NA 2 2001 2 3 8 7 3 2002 NA 4 2 1 4 2003 2 8 NA 8 5 2006 NA NA NA NA 6 2007 2 NA 8 8 7 2007 6 7 7 3
需求说明
统计各变量的年度覆盖情况:若某变量在某年份存在至少一个非NA值,则标记为1(已覆盖),否则标记为0(未覆盖),最终生成以变量为行、年份为列的表格。
期望输出
Var 2001 2002 2003 2006 2007 Var1 1 0 1 0 1 Var2 1 1 1 0 1 Var3 1 1 0 0 1 Var4 1 1 1 0 1
解决方案代码
使用dplyr结合tidyr的转置函数即可实现,代码如下:
library(dplyr) library(tidyr) # 构造原始数据框(已有数据可跳过此步) df <- tibble( ID = 1:7, Year = c(2001, 2001, 2002, 2003, 2006, 2007, 2007), Var1 = c(1, 2, NA, 2, NA, 2, 6), Var2 = c(1, 3, 4, 8, NA, NA, 7), Var3 = c(3, 8, 2, NA, NA, 8, 7), Var4 = c(NA, 7, 1, 8, NA, 8, 3) ) # 核心处理逻辑 result <- df %>% # 宽表转长表:将所有Var开头的列转为变量名和对应值 pivot_longer(cols = starts_with("Var"), names_to = "Var", values_to = "value") %>% # 按年份和变量分组,统计是否存在非NA值(转成1/0标记) group_by(Year, Var) %>% summarise(coverage = as.integer(any(!is.na(value))), .groups = "drop") %>% # 长表转宽表:年份作为列,变量作为行 pivot_wider(names_from = Year, values_from = coverage) %>% # 调整列顺序匹配期望输出 select(Var, `2001`, `2002`, `2003`, `2006`, `2007`) # 查看结果 print(result)
代码解释
pivot_longer:把原始宽格式数据转为长格式,将Var1-Var4合并为Var(变量名)和value(对应值)两列,方便后续分组统计。group_by+summarise:按年份和变量分组,用any(!is.na(value))判断该组是否存在非NA值,通过as.integer()将布尔值转为1(TRUE)或0(FALSE)。pivot_wider:把统计后的长格式数据转回宽格式,实现"变量为行、年份为列"的结构。select:调整列的顺序,与期望输出的年份排序一致(若年份顺序无要求可省略)。
内容的提问来源于stack exchange,提问作者flâneur
相关产品推荐
相关产品推荐

