如何按分组条件对行数不等的DataFrame执行除法运算?
解决方案
针对两个结构相似但code不完全匹配的DataFrame,我们可以通过合并数据框+逐列计算比值的方式实现需求,以下是具体步骤(基于dplyr包):
1. 加载依赖包
首先确保安装并加载dplyr:
install.packages("dplyr") # 首次使用需安装 library(dplyr)
2. 合并数据并计算比值
以df_II为基础(保留其所有行),通过year和code与df_I做左连接,之后对目标列做除法运算:
df_out <- df_II %>% # 按year和code合并,给两表的重复列加后缀区分 left_join(df_I, by = c("year", "code"), suffix = c("_II", "_I")) %>% # 计算各列的比值 mutate( `1` = `1_I` / `1_II`, `2` = `2_I` / `2_II`, `3` = `3_I` / `3_II`, `4` = `4_I` / `4_II`, totaal = totaal_I / totaal_II ) %>% # 保留需要的列 select(year, code, `1`, `2`, `3`, `4`, totaal)
3. 特殊情况处理
- 对于
df_I中不存在的code(比如示例中的1210),计算后会得到NA,如果需要将这些NA替换为0,可以修改mutate部分:
df_out <- df_II %>% left_join(df_I, by = c("year", "code"), suffix = c("_II", "_I")) %>% mutate( # 批量处理所有目标列,将NA替换为0 across(c(`1`, `2`, `3`, `4`, totaal), ~ replace_na(.x_I / .x_II, 0)) ) %>% select(year, code, `1`, `2`, `3`, `4`, totaal)
- 如果需要保留分数文本形式(如示例中的
1/15806),可以将计算结果转为字符串:
df_out <- df_II %>% left_join(df_I, by = c("year", "code"), suffix = c("_II", "_I")) %>% mutate( `1` = ifelse(is.na(`1_I`), NA, paste0(`1_I`, "/", `1_II`)), `2` = ifelse(is.na(`2_I`), NA, paste0(`2_I`, "/", `2_II`)), `3` = ifelse(is.na(`3_I`), NA, paste0(`3_I`, "/", `3_II`)), `4` = ifelse(is.na(`4_I`), NA, paste0(`4_I`, "/", `4_II`)), totaal = ifelse(is.na(totaal_I), NA, paste0(totaal_I, "/", totaal_II)) ) %>% select(year, code, `1`, `2`, `3`, `4`, totaal)
最终示例输出
执行分数形式的代码后,df_out的第一行结果如下:
# A tibble: 10 × 7 year code `1` `2` `3` `4` totaal <chr> <dbl> <chr> <chr> <chr> <chr> <chr> 1 2006 0 1/15806 0/9681 4/10457 4/7109 11/43053 ...
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

