今天给大家分享使用 R 语言测算区域技术专业化的方法。该方法参考自林原(2018)《技术流动对区域技术专业化的影响研究》,通过 IPC 专利分类和 RTA 指数来综合测度区域的技术专业化程度。
附件中提供了该参考文献的 PDF 文件(林原,2018),感兴趣的小伙伴可以阅读原文。
指标来源与计算原理
区域技术专业化(Regional Technological Specialization)
区域技术专业化是衡量地区在特定技术领域集聚程度的重要指标。该方法的核心思想是:
- IPC 专利分类:利用世界知识产权组织(WIPO)的 IPC 与技术领域对照表,将专利按 IPC 代码归类到 35 个技术领域
- RTA 指数(Revealed Technological Advantage):计算区域在特定技术领域的相对优势
- CV(变异系数):用调整后 RTA 的变异系数衡量区域技术专业化的整体程度

R 语言代码实现
Step 1: 加载数据
首先加载 2010 年的专利数据:
library(tidyverse) library(data.table)
cat("=== Step 1: 加载数据 ===\n")
df_raw <- read_csv("2010.csv", locale = locale(encoding = "UTF-8")) cat(sprintf("原始数据行数: %d\n", nrow(df_raw)))
df_raw %>% select(省, 市, 县, 公开公告号, IPC, newipzlid) %>% head(5)
|
Step 2: 按地区去重
专利数据可能存在重复,需要按地区(省、市、县)和不同标识进行逐级去重:
cat("\n=== Step 2: 按地区去重 ===\n")
df_raw <- df_raw %>% mutate(公开公告号_clean = str_remove(公开公告号, "[A-Z]$"))
df_raw <- df_raw %>% distinct(省, 市, 县, 公开公告号_clean, .keep_all = TRUE) cat(sprintf("按地区+公告号去重后: %d 行\n", nrow(df_raw)))
df_raw <- df_raw %>% distinct(省, 市, 县, 申请号, .keep_all = TRUE) cat(sprintf("按地区+申请号去重后: %d 行\n", nrow(df_raw)))
df_raw <- df_raw %>% distinct(省, 市, 县, newipzlid, .keep_all = TRUE) cat(sprintf("按地区+专利ID去重后: %d 行\n", nrow(df_raw)))
|
代码讲解:
- str_remove(公开公告号, “[A-Z]$”):去除公告号末尾的字母(如 CN12345A → CN12345)
- distinct():按指定变量去重,.keep_all = TRUE 保留所有变量
- 三级去重确保同一专利在同一地区只计算一次
Step 3: 读取 WIPO 表并构建 IPC 查找表
WIPO(世界知识产权组织)提供了 IPC 代码与 35 个技术领域的对照表。我们需要构建查找表,将专利的 IPC 代码映射到技术领域。
cat("\n=== Step 3: 构建IPC查找表 ===\n")
wipo <- read_csv("WIPO_IPC_and_Technology_Concordance_Table.csv", locale = locale(encoding = "UTF-8"))
wipo %>% select(序号, 大类, IPC代码) %>% head(5)
pattern_to_prefix <- function(pattern) { prefix <- str_remove(pattern, "##") prefix <- str_remove(prefix, "#") prefix <- str_remove_all(prefix, "-") return(prefix) }
|
代码讲解:
- pattern_to_prefix():将 WIPO 格式(B01D-01##)转换为前缀格式(B01D01)
- build_ipc_lookup():遍历 WIPO 表的每一行,构建 前缀 → 技术领域 的映射
- 排除规则:某些技术领域有排除规则(如”包含 A01D-15 但不包括 A01D-15-2”)
- 按前缀长度降序排序:确保先匹配更具体的前缀(如 G06F19 优先于 G06F)
Step 4: 定义 IPC 匹配函数
定义函数将 IPC 代码匹配到技术领域:
此处代码需下载讲义材料查看~
代码讲解:
- 专利可能有多个 IPC 代码(用分号分隔),需要逐一匹配
- normalized:去除 / 后面的小组号,只保留大类+主组
- 排除规则检查:如果匹配到的技术领域有排除规则,需要检查该专利的 IPC 是否命中排除前缀
Step 5: 批量匹配 IPC 到技术领域
对数据中的所有唯一 IPC 代码进行批量匹配,建立查找表:
此处代码需下载讲义材料查看~
代码优化说明:
- 先对唯一 IPC 建立查找表,再应用到全部数据,避免重复计算
- 一个专利可能匹配到多个技术领域(用分号分隔)
Step 6: 应用查找表到全部专利
将查找表应用到全部专利数据:
cat("\n=== Step 6: 应用查找表到全部专利 ===\n")
df_matched <- df_raw %>% mutate( 技术领域 = ipc_results[IPC], 技术领域 = if_else(is.na(技术领域) | 技术领域 == "", NA_character_, 技术领域), tech_count = if_else(is.na(技术领域), 0, 1) )
df_matched %>% select(newipzlid, IPC, 技术领域, tech_count)
cat(sprintf("有技术领域匹配的专利数: %d\n", sum(df_matched$tech_count > 0, na.rm = TRUE))) cat(sprintf("无匹配的专利数: %d\n", sum(df_matched$tech_count == 0, na.rm = TRUE))) cat(sprintf("总专利数: %d\n", nrow(df_matched)))
|
Step 7: 展开多值 IPC 数据
如果一个专利匹配到多个技术领域,需要展开成多行:
cat("\n=== Step 7: 展开多值IPC ===\n")
df_expanded <- df_matched %>% filter(!is.na(技术领域)) %>% select(省, 省代码, newipzlid, 技术领域) %>% separate_rows(技术领域, sep = ";") %>% distinct(省, 省代码, newipzlid, 技术领域) %>% rename(技术领域序号 = 技术领域)
df_expanded %>% filter(!is.na(省))
cat(sprintf("展开后行数: %d\n", nrow(df_expanded)))
|
代码讲解:
- separate_rows():将一个单元格中的多个值(用分号分隔)展开成多行
- distinct():去重,避免同一专利在同一技术领域重复计数
Step 8: 按省份和技术领域汇总
统计每个省份在每个技术领域的专利数量:
cat("\n=== Step 8: 按省份和技术领域汇总 ===\n")
tech_by_region <- df_expanded %>% group_by(省, 省代码, 技术领域序号) %>% summarize(专利数量 = n(), .groups = "drop")
cat(sprintf("汇总后行数: %d\n", nrow(tech_by_region))) cat(sprintf("涉及省份数: %d\n", n_distinct(tech_by_region$省)))
tech_by_region
|
Step 9: 计算 RTA 指数
根据 RTA 公式计算每个地区在每个技术领域的相对优势:
此处代码需下载讲义材料查看~
公式讲解:
- 专利数量 / tech_total:该地区在该技术领域的专利占比
- region_total / total_patents:该技术领域的专利在全国的占比
- RTA = 占比1 / 占比2:相对优势指数
- Adj_RTA:将 RTA 调整到 [0,1] 区间
Step 10: 计算 CV(变异系数)
按省份计算 Adj_RTA 的变异系数:
此处代码需下载讲义材料查看~
结果解读:
- CV 值越大,表示该区域的技术专业化程度越高
- 技术专业化高的地区:某些技术领域的 RTA 远高于其他领域(技术分布不均匀)
- 技术专业化低的地区:各技术领域的 RTA 比较均匀(技术分布分散)
Step 11: 保存结果
将计算结果保存到 CSV 文件:
cat("\n=== Step 11: 保存结果 ===\n")
tech_names <- wipo %>% select(技术领域序号 = 序号, 技术领域名称, 技术领域名称中文) %>% mutate(技术领域序号 = as.character(技术领域序号))
tech_df <- tech_by_region %>% left_join(tech_names, by = "技术领域序号") %>% arrange(省, 技术领域序号) %>% filter(!is.na(省))
write_csv(cv_by_region, "区域技术专业化CV.csv", na = "") cat("已保存: 区域技术专业化CV.csv\n")
write_csv(tech_df, "技术领域按省份汇总.csv", na = "") cat("已保存: 技术领域按省份汇总.csv\n")
cat("\n=== 完成 ===\n")
|
结果展示
区域技术专业化 CV 排名(2010年)
cv_results <- read_csv("区域技术专业化CV.csv", show_col_types = FALSE)
cv_results %>% arrange(desc(CV)) %>% select(省, CV, Total_Patents, Tech_Diversity) %>% head(10) %>% knitr::kable(digits = 4, caption = "区域技术专业化排名(前10)")
|
技术多样性分布
cv_results <- read_csv("区域技术专业化CV.csv", show_col_types = FALSE)
ggplot(cv_results, aes(x = Tech_Diversity)) + geom_histogram(bins = 20, fill = "#1f77b4", alpha = 0.7) + labs(title = "各省技术多样性分布", x = "技术领域数量", y = "省份数")
|

代码文件说明
本文档配套的 R 语言脚本文件:
| 文件 |
说明 |
main.R |
主程序,包含所有计算步骤 |
WIPO_IPC_and_Technology_Concordance_Table.csv |
WIPO IPC与技术领对照表 |
2010.csv |
2010年专利数据 |
区域技术专业化CV.csv |
计算结果:各省CV值 |
技术领域按省份汇总.csv |
计算结果:各省各技术领域的专利数量 |
点击这里跳转到 RStata 短书平台获取附件:名师讲堂|使用 R 语言测算区域技术专业化
评论