You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 05:17:17