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

在data.frame上应用strsplit()出现非预期输出的问题

R中函数处理DataFrame列时的向量化问题

问题重现

你有如下DataFrame和两个处理函数:

DataFrame代码

s_words <- c("one,uno", "two,dos", "three,tres", "four,cuatro")
n_nums <- c(10, 20, 30, 40)
df1 <- data.frame(n_nums, s_words) 

自定义函数代码

f_op1 <- function(s_input) {
  s_ret <- paste0("***", s_input, "***")
  return(s_ret)
}

f_op2 <- function(s_input) {
  a_segments <- unlist(strsplit(s_input, split="\\W+"))
  s_eng <- a_segments[1]
  s_spa <- a_segments[2]
  s_ret <- paste0("*", s_eng, "***", s_spa, "*")
  return(s_ret)
}

当你将函数应用到DataFrame列时:

df1$s_op1 <- f_op1(df1$s_words)
df1$s_op2 <- f_op2(df1$s_words)

发现s_op2列所有行均为*one***uno*,而非每行对应s_words字段拆分后的拼接结果(比如第二行应为*two***dos*)。

问题原因

核心问题出在strsplit的行为上:

  • 当传入向量给strsplit时,它返回的是一个列表,列表中每个元素对应原向量里单个字符串的拆分结果。
  • 你用unlist()把整个列表拆成了一个扁平向量,此时a_segments[1]和a_segments[2]只会取到原向量第一个字符串拆分后的前两个元素,导致所有行都复用了这个结果。

解决方案

方法1:修改函数,遍历处理每个元素

修改f_op2,用sapply遍历向量中的每个字符串,确保每行都得到独立的处理结果:

f_op2 <- function(s_input) {
  sapply(s_input, function(x) {
    a_segments <- unlist(strsplit(x, split="\\W+"))
    paste0("*", a_segments[1], "***", a_segments[2], "*")
  })
}

或者用purrr包的map_chr(更简洁的遍历方式):

library(purrr)
f_op2 <- function(s_input) {
  map_chr(s_input, function(x) {
    a_segments <- strsplit(x, split="\\W+")[[1]]
    paste0("*", a_segments[1], "***", a_segments[2], "*")
  })
}

方法2:用tidyverse工具拆分后拼接

如果你的实际逻辑允许,也可以不用自定义函数,直接用tidyr和dplyr完成拆分与拼接:

library(tidyr)
library(dplyr)

df1 <- df1 %>%
  separate(s_words, into = c("eng", "spa"), sep = "\\W+", remove = FALSE) %>%
  mutate(s_op2 = paste0("*", eng, "***", spa, "*")) %>%
  select(-eng, -spa)

验证结果

应用修改后的函数或tidyverse代码后,df1$s_op2会得到预期结果:

n_numss_wordss_op2
10one,unoone*uno
20two,dostwo*dos
30three,tresthree*tres
40four,cuatrofour*cuatro

内容的提问来源于stack exchange,提问作者Alejandro Bermúdez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 00:52:45