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

如何在R数据框中实现对应Stata逻辑的多药物分类

在R中实现Stata风格的多标签药物分类逻辑

没问题,我帮你把Stata里的药物分类逻辑转到R,还支持多标签分类——这比Stata里每次replace覆盖的方式更灵活,正好满足你要保留多个分类的需求。

第一步:理解原Stata代码逻辑

你的Stata代码是通过strmatch(upper(drug), "XXX*")匹配药物名称(转大写后以指定前缀开头),然后给class字段赋值。但Stata的replace是覆盖式的,一个药物如果匹配多个规则,只会保留最后一次赋值的分类。而你需要的是收集所有匹配的分类,所以我们用R的列表和字符串匹配工具来实现。

第二步:准备R代码实现

首先加载常用的工具包(如果没安装先运行install.packages(c("dplyr", "stringr", "purrr"))):

library(dplyr)
library(stringr)
library(purrr)

然后把你的Stata分类规则整理成R的列表结构,键是分类名称,值是对应的药物前缀(去掉原代码里的*,因为我们会用开头匹配的逻辑):

# 定义药物分类规则
drug_class_rules <- list(
  "ACE Inhibitor" = c("CAPTOPRIL", "ENALAPRIL", "ENALAPRILAT", "FOSINOPRIL", "LISINOPRIL", "RAMIPRIL"),
  "Acne Medication" = c("ADAPALENE", "ADAPALENE/BENZOYL PEROXIDE", "BENZOYL PEROXIDE", "BENZOYL PEROXIDE/CLINDAMYCIN", "ISOTRETINOIN", "ERYTHROMYCIN/TRETINOIN"),
  "Acne Medication/Acute Promyelocytic Leukemia Medication" = c("TRETINOIN"),
  "Alpha Agonist" = c("XYLOMETAZOLINE"),
  "Alpha Blocker" = c("DOXAZOSIN", "PHENOXYBENZAMINE", "PHENTOLAMINE", "PRAZOSIN", "TAMSULOSIN", "TERAZOSIN"),
  "Alpha/Beta Blocker" = c("CARVEDILOL", "LABETALOL"),
  "Alpha-1 Agonist" = c("PHENYLEPHRINE", "MIDODRINE"),
  "Alpha-2 Agonist" = c("CLONIDINE", "DEXMEDETOMIDINE"),
  "Anaesthetic, general" = c("KETAMINE", "THIOPENTAL"),
  "Anaesthetic, local" = c("BENZOCAINE", "BUPIVACAINE", "BUPIVACAINE/FENTANYL", "TETRACAINE", "XYLOCAINE"),
  "Anaesthetic, local/Antiarrythmic" = c("LIDOCAINE"),
  "Anaesthetic, local/Antiseptic" = c("HEXYLRESORCINOL"),
  "Anaesthetic, topical" = c("LIDOCAINE/PRILOCAINE", "PROPARACAINE"),
  "Analgesic" = c("ACETAMINOPHEN", "BELLADONNA & OPIUM SUPPOSITORY")
)

接下来处理你的数据框(假设数据框名为drug_df):

# 先把药物名称转成大写,统一匹配规则
drug_df <- drug_df %>%
  mutate(drug_upper = str_to_upper(drug))

# 编写函数:输入大写药物名,返回所有匹配的分类
get_matching_classes <- function(drug_name, rules) {
  # 检查每个分类下的药物前缀是否匹配当前药物的开头
  matches <- map_lgl(rules, ~any(str_starts(drug_name, .x)))
  # 返回所有匹配的分类名称
  names(rules)[matches]
}

# 给每一行添加多分类列
drug_df <- drug_df %>%
  # 生成列表列,每个元素是该药物的所有分类向量
  mutate(classes = map(drug_upper, get_matching_classes, rules = drug_class_rules),
         # 可选:把分类转成逗号分隔的字符串,方便查看
         classes_str = map_chr(classes, ~paste(.x, collapse = ", ")))

第三步:验证结果

用你提供的样本数据测试:

  • 药物Amlodipine、Cefprozil、Clobazam不在规则里,所以classes是空向量,classes_str是空字符串。
  • 如果有药物是TRETINOIN,会匹配到Acne Medication/Acute Promyelocytic Leukemia Medication。
  • 如果是ERYTHROMYCIN/TRETINOIN,会匹配到Acne Medication(不会被TRETINOIN*匹配,因为它的开头是ERYTHROMYCIN,和原Stata逻辑一致)。

可选:Base R版本(不用tidyverse)

如果你不想用tidyverse包,用Base R也能实现:

# 转大写
drug_df$drug_upper <- toupper(drug_df$drug)

# 生成分类列
drug_df$classes <- lapply(drug_df$drug_upper, function(x) {
  sapply(names(drug_class_rules), function(c) {
    any(startsWith(x, drug_class_rules[[c]]))
  }) %>% which() %>% names()
})

# 转成字符串列
drug_df$classes_str <- sapply(drug_df$classes, function(x) paste(x, collapse = ", "))

这样就完美复刻了Stata的匹配逻辑,同时支持一个药物对应多个分类的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:49:07