基于R语言data.frame,查找每行对应b列最后缺失值的c列取值
解决方法:按分组提取最后一个NA对应的c值
先把你的原始数据框再贴一遍,方便大家对照:
df <- data.frame( a = c(rep("a", 3), rep("b", 3), rep("c", 3)), b = c(NA, NA, "test", NA, "test", "test", NA, NA, "test"), c = c("trial", "test", "trial", "trial", "test", "trial", "trial", "trial", "trial"), stringsAsFactors = FALSE )
咱们的目标是:针对每个a的分组,找到该分组内b列最后一个缺失值(NA)对应的c列取值,然后把这个值填充到该分组所有行的try列中。下面给你两种常用的实现方法:
方法1:用dplyr(tidyverse风格)
这种方法代码可读性高,适合习惯tidyverse的朋友:
library(dplyr) df_with_try <- df %>% group_by(a) %>% mutate( # 找到当前分组里b列是NA的所有行的位置,取最大的那个(也就是最后一个NA的位置) last_na_index = max(which(is.na(b))), # 根据这个位置提取对应的c值,赋值给try列 try = c[last_na_index] ) %>% ungroup() # 查看结果 print(df_with_try)
运行后得到的结果如下:
# A tibble: 9 × 5 a b c last_na_index try <chr> <chr> <chr> <int> <chr> 1 a NA trial 2 test 2 a NA test 2 test 3 a test trial 2 test 4 b NA trial 1 trial 5 b test test 1 trial 6 b test trial 1 trial 7 c NA trial 2 trial 8 c NA trial 2 trial 9 c test trial 2 trial
方法2:用base R(不需要额外包)
如果你不想加载额外的包,用base R也能轻松实现:
# 先按a分组,计算每个分组最后一个NA对应的c值 group_last_na_c <- tapply(seq_len(nrow(df)), df$a, function(idx) { # 拿到当前分组的b列数据 group_b <- df$b[idx] # 找到所有NA的位置 na_positions <- which(is.na(group_b)) # 如果有NA,取最后一个对应的c值;没有的话返回NA if (length(na_positions) > 0) { df$c[idx][max(na_positions)] } else { NA_character_ } }) # 把每个分组的结果匹配到原数据框的每一行 df$try <- group_last_na_c[df$a] # 查看结果 print(df)
这个方法的结果和上面dplyr的完全一致,只是用了base R的tapply函数来处理分组逻辑。
内容的提问来源于stack exchange,提问作者arg0naut91
相关产品推荐
相关产品推荐

