如何筛选R数据框中每个国家最后一个非NA的Value值?
解决方法
方法1:使用tidyverse(dplyr)包
这是日常数据分析中最常用的简洁写法:
# 首次使用时先安装包 # install.packages("dplyr") library(dplyr) # 原数据 df <- data.frame( Country=c("Aruba","Aruba","Aruba","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Butan","Butan","Belize"), Year=c("2007","2008","2009","2006","2007","2008","2009","2006","2009","2006"), Value=c(158,196,NA,156,140,693,854,NA,904,925)) # 筛选每个国家最后一个非NA的Value行 result <- df %>% # 将Year从字符型转为数值型,确保年份排序逻辑准确 mutate(Year = as.numeric(Year)) %>% # 按国家分组 group_by(Country) %>% # 过滤掉Value为NA的行 filter(!is.na(Value)) %>% # 取每组的最后一行(即最新年份的有效数据) slice_tail(n = 1) %>% # 取消分组结构 ungroup() print(result)
执行后输出结果:
# A tibble: 4 × 3 Country Year Value <chr> <dbl> <dbl> 1 Afghanistan 2009 854 2 Aruba 2008 196 3 Belize 2006 925 4 Butan 2009 904
方法2:基础R实现(无需额外包)
如果不想依赖第三方包,用基础R函数也能完成:
# 原数据 df <- data.frame( Country=c("Aruba","Aruba","Aruba","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Butan","Butan","Belize"), Year=c("2007","2008","2009","2006","2007","2008","2009","2006","2009","2006"), Value=c(158,196,NA,156,140,693,854,NA,904,925)) # 转换Year为数值型 df$Year <- as.numeric(df$Year) # 按国家分组处理,过滤非NA行后取最后一行 result <- do.call(rbind, lapply(split(df, df$Country), function(group) { non_na_rows <- group[!is.na(group$Value), ] # 避免无有效数据的国家报错 if (nrow(non_na_rows) > 0) tail(non_na_rows, 1) else NULL })) print(result)
方法3:data.table包(适合大数据集)
如果处理百万级以上的大数据,data.table的运行效率更高:
# 首次使用时先安装包 # install.packages("data.table") library(data.table) # 原数据 df <- data.frame( Country=c("Aruba","Aruba","Aruba","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Butan","Butan","Belize"), Year=c("2007","2008","2009","2006","2007","2008","2009","2006","2009","2006"), Value=c(158,196,NA,156,140,693,854,NA,904,925)) # 转换为data.table对象并处理Year列 setDT(df)[, Year := as.numeric(Year)] # 按国家分组,过滤非NA后取每组最后一行 result <- df[!is.na(Value), .SD[.N], by = Country] print(result)
内容的提问来源于stack exchange,提问作者silent_hunter
相关产品推荐
相关产品推荐

