如何通过str_detect等字符串匹配函数连接不等长数据框?
解决方案
方法一:使用purrr逐个匹配(最直接)
利用purrr::map_dbl遍历dfSearch的每个值,在df中找到匹配的行并提取对应的line,最后手动添加d的行:
library(tidyverse) # 示例数据 df <- tibble(value = c("a <- 1:3", "b <- function()", "c <- rnorm(1:10)", "d <- c(x, y, z)"), line = 1:4) dfSearch <- c("a", "b", "c") %>% as_tibble() # 为每个搜索值匹配对应的line dfSearch <- dfSearch %>% mutate(line = map_dbl(value, ~ df$line[str_detect(df$value, .x)])) # 添加d的行(按需求) final_df <- dfSearch %>% add_row(value = "d", line = NA) print(final_df)
运行结果:
# A tibble: 4 × 2 value line <chr> <dbl> 1 a 1 2 b 2 3 c 3 4 d NA
方法二:先提取变量名再做连接
先从df的字符串中提取开头的变量名,再和dfSearch做左连接,最后补充d的行:
library(tidyverse) df <- tibble(value = c("a <- 1:3", "b <- function()", "c <- rnorm(1:10)", "d <- c(x, y, z)"), line = 1:4) %>% # 提取字符串开头的变量名 mutate(var_name = str_extract(value, "^\\w")) dfSearch <- c("a", "b", "c") %>% as_tibble() %>% rename(var_name = value) # 左连接匹配 matched_df <- dfSearch %>% left_join(df %>% select(var_name, line), by = "var_name") %>% rename(value = var_name) # 添加d的行 final_df <- matched_df %>% add_row(value = "d", line = NA)
方法三:笛卡尔积过滤
先做两个数据框的笛卡尔积,再筛选匹配的行,最后整理结果:
library(tidyverse) df <- tibble(value = c("a <- 1:3", "b <- function()", "c <- rnorm(1:10)", "d <- c(x, y, z)"), line = 1:4) dfSearch <- c("a", "b", "c") %>% as_tibble() %>% rename(search_val = value) # 笛卡尔积+过滤匹配项 matched_df <- dfSearch %>% cross_join(df) %>% filter(str_detect(df$value, search_val)) %>% select(search_val, line) %>% rename(value = search_val) # 添加d的行 final_df <- matched_df %>% add_row(value = "d", line = NA)
错误原因说明
你之前的代码报错是因为str_detect要求输入的string和pattern长度一致(或其中一个长度为1),而你传入的df$value长度为4、dfSearch$value长度为3,无法循环回收,因此触发错误。上面的方法通过逐个处理、提取变量名或笛卡尔积的方式避开了这个问题。
内容的提问来源于stack exchange,提问作者ksinva
相关产品推荐
相关产品推荐

