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

如何用R语言实现按特定字符拆分字符串并转换数据框?

R语言:将指定数据转换为目标格式的方法

需求示例

原始数据:

data <- data.frame(ID = 1, Info = "Zebra fish (one)--Hello; blah", Value = 7)

目标格式:

new_data <- data.frame(ID = 1, CATEGORY = "Zebra Fish", TYPE1 = "one", TYPE2 = "Hello", Value = 7)

问:有没有可实现上述转换的工具函数?自己编写的代码无法正常运行,代码如下:

# Function to parse the info column
parse_info <- function(info) {
  # Split by parentheses and dashes
  parts1 <- unlist(strsplit(info, "\\(|\\)"))
  category <- trimws(parts1[1])
  type1 <- trimws(parts1[2])
  
  # Further split by dashes and semicolons
  parts2 <- unlist(strsplit(parts1[3], "--|;"))
  type2 <- trimws(parts2[1])
  
  return(c(category, type1, type2))
}

# Apply the function to each row
parsed <- t(apply(data, 1, function(row) {
  c(row['ID'], parse_info(row['Info']), row['Value'])
}))

# Create a new data frame
new_data <- as.data.frame(parsed, stringsAsFactors = FALSE)
names(new_data) <- c("ID", "CATEGORY", "TYPE1", "TYPE2", "VALUE")

问题分析

你写的代码存在几个核心问题:

  1. apply(data, 1, ...)会把数据框的行强制转为字符向量,导致ID和Value丢失数值类型
  2. 字符串分割后parts1[3]的内容是--Hello; blah,用--|;分割后parts2[1]为空字符串,无法提取出Hello
  3. 目标格式的CATEGORY要求首字母大写(Zebra Fish),原始数据是Zebra fish,代码未处理大小写转换

解决方案

方法1:用tidyr::extract实现(简洁高效)

借助tidyverse工具包的extract函数,通过正则表达式直接提取分组,一步完成转换:

library(tidyverse)

new_data <- data %>%
  extract(
    Info,
    into = c("CATEGORY", "TYPE1", "TYPE2"),
    regex = "(.*?)\\s*\\((.*?)\\)--(.*?);.*",
    remove = FALSE  # 可选参数,保留原Info列
  ) %>%
  mutate(
    CATEGORY = str_to_title(CATEGORY),  # 自动将每个单词首字母大写
    ID = as.integer(ID),
    Value = as.integer(Value)
  ) %>%
  select(ID, CATEGORY, TYPE1, TYPE2, Value)

方法2:修复原有自定义函数

调整字符串处理逻辑,同时保留数据类型:

library(dplyr)

parse_info <- function(info) {
  # 提取括号前的分类内容并处理大小写
  category <- str_extract(info, "^.*?(?=\\s*\\()") %>% trimws() %>% str_to_title()
  # 提取括号内的TYPE1内容
  type1 <- str_extract(info, "(?<=\\().*?(?=\\))") %>% trimws()
  # 提取--和;之间的TYPE2内容
  type2 <- str_extract(info, "(?<=--).*?(?=;)") %>% trimws()
  
  return(data.frame(CATEGORY = category, TYPE1 = type1, TYPE2 = type2, stringsAsFactors = FALSE))
}

new_data <- data %>%
  rowwise() %>%
  bind_cols(parse_info(Info)) %>%
  ungroup() %>%
  select(ID, CATEGORY, TYPE1, TYPE2, Value)

方法3:基础R原生实现(无需额外包)

parse_info <- function(info) {
  # 提取分类内容
  category <- sub("\\s*\\(.*", "", info) %>% trimws()
  # 手动处理首字母大写
  category <- gsub("(^|\\s)([a-z])", "\\1\\U\\2", category, perl = TRUE)
  # 提取TYPE1
  type1 <- sub(".*\\((.*?)\\).*", "\\1", info) %>% trimws()
  # 提取TYPE2
  type2 <- sub(".*--(.*?);.*", "\\1", info) %>% trimws()
  
  return(list(CATEGORY = category, TYPE1 = type1, TYPE2 = type2))
}

# 逐行处理并合并结果
parsed_list <- lapply(1:nrow(data), function(i) {
  row <- data[i, ]
  parsed <- parse_info(row$Info)
  data.frame(
    ID = row$ID,
    CATEGORY = parsed$CATEGORY,
    TYPE1 = parsed$TYPE1,
    TYPE2 = parsed$TYPE2,
    Value = row$Value,
    stringsAsFactors = FALSE
  )
})

new_data <- do.call(rbind, parsed_list)

以上三种方法均可生成符合要求的new_data格式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:22:35