如何按inst分组查找满足当前与下一个val相等的swi值?
问题描述
我有一个包含3列的dataframe,代码如下:
df <- data.frame( "inst" = rep(c('a','b','c','d'),4), "swi" = c(rep(0.05,4), rep(0.10,4), rep(0.15,4), rep(0.20,4)), "val" = c(10,12,8,15,11,14,10,15,11,15,13,15,11,15,16,15) )
该dataframe内容如下:
# A tibble: 16 x 3 # Groups: inst [4] inst swi val <fct> <dbl> <dbl> 1 a 0.05 10 2 b 0.05 12 3 c 0.05 8 4 d 0.05 15 5 a 0.1 11 6 b 0.1 14 7 c 0.1 10 8 d 0.1 15 9 a 0.15 11 10 b 0.15 15 11 c 0.15 13 12 d 0.15 15 13 a 0.2 11 14 b 0.2 15 15 c 0.2 16 16 d 0.2 15
需求:针对每个唯一的inst,找到对应的swi值,要求该swi对应的val与下一个swi对应的val相等;若不存在满足条件的swi,则返回-1。期望输出如下:
inst swi a 0.1 b 0.15 c -1 d 0.05
解决方案
使用dplyr包可以高效实现这个需求,以下是具体代码:
library(dplyr) result <- df %>% # 确保每个inst下的swi按升序排列,保证lead取的是下一个更大的swi对应的值 arrange(inst, swi) %>% group_by(inst) %>% # 获取当前行的下一行val值 mutate(next_val = lead(val)) %>% # 筛选当前val与下一个val相等的行 filter(val == next_val) %>% # 保留inst和swi列,若有多个符合条件的swi,取第一个(最小的) select(inst, swi) %>% slice_head(n = 1) %>% ungroup() %>% # 关联所有唯一inst,确保没有符合条件的inst也被保留 right_join(distinct(df, inst), by = "inst") %>% # 无符合条件的swi替换为-1 mutate(swi = ifelse(is.na(swi), -1, swi)) %>% arrange(inst) print(result)
执行代码后输出:
# A tibble: 4 x 2 inst swi <chr> <dbl> 1 a 0.1 2 b 0.15 3 c -1 4 d 0.05
关键逻辑说明
arrange(inst, swi):保证每个inst分组内的swi是从小到大排序的,确保lead(val)获取的是下一个更高swi对应的vallead(val):提取当前行的下一行val,用于比较当前和下一个swi的val是否相等slice_head(n = 1):如果某个inst有多个符合条件的swi(比如d的0.05、0.1、0.15都满足),取最小的那个swiright_join(distinct(df, inst)):确保所有原始inst都被包含,避免丢失没有符合条件的行ifelse(is.na(swi), -1, swi):将无匹配的swi值替换为-1
内容的提问来源于stack exchange,提问作者Ilhan
相关产品推荐
相关产品推荐

