在dplyr的mutate()中使用which()出现错误的问题求解
问题解决:匹配数据框并获取对应行号
需求
有两个数据框df1和df2,需要在df2中新增phone_ind列,存储df1$telephone中与df2$phone匹配的所有行号。
数据定义
df1 <- data.frame( telephone = c("1231231234", "2342342345", "3453453456", "1231231234"), email = c("a@email.com", "b@email.com", "c@email.com", "d@mail.com") ) df2 <- data.frame( phone = c("1231231234", "2342342345", "3453453456") )
尝试的代码及问题
原代码尝试用dplyr::mutate结合which()和str_flatten()实现,但出现警告longer object length is not a multiple of shorter object length,且phone_ind结果全部为1, 2, 3, 4,完全不符合预期:
df2 <- df2 %>% mutate( phone_ind = str_flatten(which(df1$telephone == phone), collapse = ", ") )
问题原因
直接在mutate中执行df1$telephone == phone时,phone是df2的整列向量,会触发循环补齐规则,导致每个phone值都和整个df1$telephone向量做了错误的匹配逻辑,最终得到错误的行号集合。
解决方法
方法1:使用purrr::map_chr逐行处理
利用map_chr遍历df2$phone的每个元素,单独匹配df1中的行号并拼接:
library(dplyr) library(purrr) library(stringr) df2 <- df2 %>% mutate( phone_ind = map_chr(phone, ~ str_flatten(which(df1$telephone == .x), collapse = ", ")) )
方法2:先分组汇总再合并
先对df1按telephone分组,汇总对应的行号,再和df2合并:
library(dplyr) library(stringr) # 先处理df1,得到每个telephone对应的行号字符串 df1_summary <- df1 %>% mutate(row_num = row_number()) %>% group_by(telephone) %>% summarise(phone_ind = str_flatten(row_num, collapse = ", "), .groups = "drop") # 合并到df2 df2 <- df2 %>% left_join(df1_summary, by = c("phone" = "telephone"))
方法3:使用rowwise()逐行计算
用rowwise()让mutate逐行处理每个phone值:
library(dplyr) library(stringr) df2 <- df2 %>% rowwise() %>% mutate( phone_ind = str_flatten(which(df1$telephone == phone), collapse = ", ") ) %>% ungroup()
运行以上任意方法后,df2的结果都会符合预期:
phone phone_ind 1 1231231234 1, 4 2 2342342345 2 3 3453453456 3
内容的提问来源于stack exchange,提问作者lane-h-rogers
相关产品推荐
相关产品推荐

