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

如何在R(dplyr 0.7.4)中批量按指定长度截断数据框列?

批量截断数据框指定字段至不同长度的解决方案

问题背景

现有如下数据框,需要将first_name截断至3个字符,last_name截断至5个字符:

library(dplyr)

id <- c(1111, 2222, 3333, 4444, 5555)
first_name <- c("Jonathan", "Sally", "Courtney", "Stephen", "Matthew")
last_name <- c("Johnson", "Montgomery", "Cunningham", "Stephenson", "Matthews")
Height <- c(200, 160, 170, 180, 190)
 
df <- data.frame(id, first_name, last_name, Height, stringsAsFactors = FALSE)

编写了单个字段截断函数,单独调用时可正常运行:

truncate_fields <- function(df, field, n) {
  df_tr <-
    mutate(df, {{field}} := str_trunc({{field}}, n, ellipsis = ""))
  return(df_tr)
}

但尝试通过循环批量处理时:

fields <- c("first_name", "last_name")
lengths <- c(3, 5)

for(i in 1:length(fields)) {
  df <-
    truncate_fields(df, noquote(fields)[i], lengths[i])
}

出现报错:

Error in `splice()`:
! The LHS of `:=` must be a string or a symbol

使用lapply/mapply也未成功,当前使用dplyr 0.7.4版本,需解决批量处理问题。

解决方法

方法1:修改原函数适配字符串输入

dplyr 0.7.4不支持新版的{{}}语法处理字符串输入,需要将字符串字段名转换为符号后注入表达式:

library(stringr) # 需加载stringr包以使用str_trunc

truncate_fields <- function(df, field, n) {
  field_sym <- sym(field) # 将字符串转为符号
  df_tr <- mutate(df, !!field_sym := str_trunc(!!field_sym, n, ellipsis = ""))
  return(df_tr)
}

修改后即可正常循环调用:

fields <- c("first_name", "last_name")
lengths <- c(3, 5)

for(i in seq_along(fields)) {
  df <- truncate_fields(df, fields[i], lengths[i])
}

方法2:使用mutate_at+purrr::map2批量处理(更简洁)

无需单独编写函数,直接结合mutate_at和map2实现字段与截断长度的配对处理:

library(stringr)
library(purrr)

df <- df %>%
  mutate_at(vars(fields), ~map2(., lengths, function(x, n) str_trunc(x, n, ellipsis = "")))

报错原因

原函数中的{{field}}(拥抱语法)是dplyr 1.0.0及以上版本引入的特性,用于直接处理符号类型的字段名。但在0.7.4版本中,传入字符串时{{field}}无法正确转换为合法的符号,导致:=左侧不符合语法要求,从而触发报错。通过sym()转换字符串为符号,再用!!(解引用)注入表达式,即可适配旧版本的tidyeval规则。

内容的提问来源于stack exchange,提问作者Annabanana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:22:53