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

如何在R语言中识别并转换混合文本中的罗马数字为整数?

解决方案

首先加载所需包并处理原始数据中的字符型"NA":

library(stringr)
library(gtools)

# 原始数据
x <- data.frame(col = c("15", "NA", "0", "Red", "iv", "Logic", "ix. Sweet", "VIII - Apple", 
                        "Big XVI", "WeirdVII", "XI: Small"))
# 将字符型"NA"转为真正的NA值
x$col[x$col == "NA"] <- NA

问题原因

你之前的代码错误是因为str_extract会提取字符串中单个的罗马数字字母(比如Logic里的i),而roman2int("i")会返回1,导致纯字符被错误转换。我们需要准确识别有效的罗马数字序列,排除单词内部的单个罗马字母。

完整转换代码

编写验证有效罗马数字的辅助函数,再实现转换逻辑:

# 辅助函数:验证字符串是否为有效罗马数字
is_valid_roman <- function(s) {
  s_upper <- toupper(s)
  # 仅允许罗马数字字符
  if (!str_detect(s_upper, "^[IVXLCDM]+$")) return(FALSE)
  # 禁止四个连续相同字符
  if (str_detect(s_upper, "(.)\\1{3,}")) return(FALSE)
  # 禁止非法的前置小数字组合(如IL、IC等)
  invalid_patterns <- c("IL", "IC", "ID", "IM", "VL", "VC", "VD", "VM", "XD", "XM")
  if (any(str_detect(s_upper, paste(invalid_patterns, collapse = "|")))) return(FALSE)
  # 尝试转换,无报错则有效
  tryCatch({
    roman2int(s_upper)
    TRUE
  }, error = function(e) FALSE)
}

# 核心转换函数
convert_roman_col <- function(vec) {
  sapply(vec, function(s) {
    # 处理NA值
    if (is.na(s)) return(NA)
    
    # 优先转换整数型字符串(如"15"、"0")
    num <- suppressWarnings(as.integer(s))
    if (!is.na(num)) return(num)
    
    # 检查整个字符串是否为有效罗马数字(如"iv")
    if (is_valid_roman(s)) {
      return(roman2int(toupper(s)))
    }
    
    # 提取字符串中长度≥2的罗马数字序列(避免匹配单词内部的单个字母)
    roman_matches <- str_extract_all(s, "[IVXivx]{2,}")[[1]]
    
    # 过滤出有效的罗马数字
    valid_matches <- roman_matches[sapply(roman_matches, is_valid_roman)]
    
    # 转换第一个有效匹配的罗马数字
    if (length(valid_matches) > 0) {
      return(roman2int(toupper(valid_matches[1])))
    }
    
    # 无有效罗马数字则返回原字符串
    return(s)
  })
}

# 应用转换函数
x$converted_col <- convert_roman_col(x$col)

转换结果

运行后x$converted_col的结果为:

[1] 15  NA   0 "Red"   4 "Logic"   9   8  16   7  11

完全符合你的预期需求。

内容的提问来源于stack exchange,提问作者mr.questions

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 14:38:00