如何在R中基于已有行计算添加新行(使用dplyr/tidyverse)
用tidyverse实现基于现有数据生成新行的可扩展方案
1. 创建原始数据框
首先用tibble构造你提供的原始数据:
library(tidyverse) df <- tibble( ID = c("A1", "A2", "B1", "C4", "D8"), number = c(5, 10, 7, 3, 2) )
2. 定义可扩展的新行规则
把需要生成的新行规则单独整理成规则表,后续要加新行直接在这里追加条目即可,无需修改核心逻辑:
# 规则表:每行对应一个新行,包含新ID和计算逻辑 new_rows_rules <- tibble( new_ID = c("B2", "C7", "A3", "C9"), calculation = list( quote(df$number[df$ID == "B1"]), # B2取B1的number quote(df$number[df$ID == "C4"]), # C7取C4的number quote((df$number[df$ID == "A1"] + df$number[df$ID == "A2"]) / 2), # A3取A1+A2的平均值 quote(df$number[df$ID == "A2"]) # C9取A2的number ) )
3. 生成新行并合并到原始数据
用purrr的map_dbl计算每个新行的number值,再通过bind_rows合并:
# 计算新行的number值 new_rows <- new_rows_rules %>% mutate(number = map_dbl(calculation, ~ eval(.x))) %>% select(ID = new_ID, number) # 合并原始数据与新行 final_df <- bind_rows(df, new_rows) # 查看最终结果 final_df
运行后得到的结果和预期完全一致:
# A tibble: 9 × 2 ID number <chr> <dbl> 1 A1 5 2 A2 10 3 B1 7 4 C4 3 5 D8 2 6 B2 7 7 C7 3 8 A3 7.5 9 C9 10
4. 扩展方案:添加更多新行
如果需要新增其他行,比如要加ID=D9, number=D8的2倍,只需要在new_rows_rules里追加一行:
new_rows_rules <- add_row(new_rows_rules, new_ID = "D9", calculation = quote(df$number[df$ID == "D8"] * 2) )
重新运行合并代码即可自动生成新行。
另一种简洁的规则定义方式(命名列表)
你也可以用命名列表来定义规则,键为新ID,值为计算函数,代码更紧凑:
new_rows_list <- list( "B2" = ~ .x$number[.x$ID == "B1"], "C7" = ~ .x$number[.x$ID == "C4"], "A3" = ~ (.x$number[.x$ID == "A1"] + .x$number[.x$ID == "A2"]) / 2, "C9" = ~ .x$number[.x$ID == "A2"] ) # 生成新行并合并 final_df_alt <- bind_rows( df, map_dfr(new_rows_list, ~ .x(df), .id = "ID") %>% rename(number = value) )
内容的提问来源于stack exchange,提问作者flâneur
相关产品推荐
相关产品推荐

