R语言中如何按字符位置合并df与df2两个DataFrame?
实现DataFrame合并匹配的两种方法
方法一:使用dplyr和tidyr包
适合熟悉tidyverse语法的用户,步骤清晰易读:
- 先给
df添加每个字符串覆盖的vec1位置区间(起始start和结束end):
library(dplyr) library(tidyr) df <- df %>% mutate( start = lag(position, default = 0) + 1, end = position )
- 交叉连接
df和df2,筛选出df2中位置落在df区间内的记录,再按df的行分组聚合名称:
df3 <- df %>% # 交叉连接两个表,建立所有可能的匹配关系 left_join(df2, by = character(), relationship = "many-to-many") %>% # 筛选出df2的position在当前df行的start和end之间的记录 filter(between(position.y, start, end)) %>% # 按df的position和string分组,将name用逗号拼接 group_by(position.x, string) %>% summarise(name = paste(name, collapse = ", "), .groups = "drop") %>% # 右连接回原df,保留所有原行 right_join(df, by = c("position.x" = "position", "string")) %>% # 整理列顺序和名称,将空字符串转为NA select(position = position.x, string, name) %>% mutate(name = ifelse(name == "", NA_character_, name))
方法二:使用Base R
无需加载额外包,用原生R函数实现:
- 给
df添加位置区间:
# 计算每个string的起始位置:前一个position+1,第一个起始为1 df$start <- c(1, df$position[-nrow(df)] + 1) df$end <- df$position
- 匹配
df2的每个位置对应的df行,再聚合名称:
# 找出每个df2的position属于df的哪一行 df2$df_row <- sapply(df2$position, function(p) which(p >= df$start & p <= df$end)) # 按所属df行分组,拼接name name_list <- tapply(df2$name, df2$df_row, paste, collapse = ", ") # 构建最终的df3 df3 <- df[, c("position", "string")] df3$name <- NA_character_ # 将聚合后的name对应填充到df3中 df3$name[as.integer(names(name_list))] <- name_list
两种方法运行后,都能得到目标结果:
> df3 position string name 1 4 MPPA pear 2 10 APARLA apple, lemon 3 12 LA <NA> 4 20 LGLGLWLG <NA> 5 27 ALAGGPG apricot, peach 6 30 RGC grape
内容的提问来源于stack exchange,提问作者Jen
相关产品推荐
相关产品推荐

