名师讲堂|使用 Stata 筛选绿色技术专利(国家知识产权局标准)

教育   2025-01-14 12:00   福建  


欢迎各位名师讲堂会员参加明晚 8 点的直播课:「使用 Stata 筛选绿色技术专利(国家知识产权局标准)」

前不久给大家分享过一些绿色技术相关的专利数据。由于绿色专利的分类标准中有全部涉及和部分涉及两种,所以筛选起来很困难,今天的课程中我们将会讲解如何进行这种筛选。

1985~2024 年绿色专利申请与授权数据(国家知识产权局标准):https://rstata.duanshu.com/#/brief/course/9cfa513db3a54891bef466caac9e6a62

pdf 转 xlsx

筛选绿色专利使用的标准是国家知识产权局印发的《绿色技术专利分类体系》,附件中有 pdf 文件。

从该 pdf 文件中可以提取绿色专利技术专利分类体系表:绿色技术专利分类体系-table.pdf,这可以借助浏览器的打印功能得到。使用 Adobe Acrobat 软件可以把 pdf 文件转换成 xlsx 文件,附件中的 绿色技术专利分类体系-table.xlsx 就是转换结果。简单手动整理后再使用 Stata 处理下:

import excel using "绿色技术专利分类体系-table.xlsx"clear first 
drop D 
compress 
foreach i of varlist _all {
 cap format `i' %10s 
}
replace 国际专利分类 = 国际专利分类[_n] + 国际专利分类[_n + 1] if mi(技术分支编号[_n + 1]) 
drop if mi(技术分支编号)
gen 绿色专利分类ID = _n 
order 绿色专利分类ID

gen temp = ustrregexs(0) if ustrregexm(国际专利分类, "\n")
replace 国际专利分类 = subinstr(国际专利分类, temp, "", .)
drop temp 

gen temp = ustrregexs(0) if ustrregexm(技术分支名称, "\n")
replace 技术分支名称 = subinstr(技术分支名称, temp, "", .)
drop temp 

replace 国际专利分类 = subinstr(国际专利分类, " """, .)
replace 国际专利分类 = subinstr(国际专利分类, ";"",", .)

split 国际专利分类, parse("部分涉及")
foreach i of varlist _all {
 cap format `i' %10s 
}
replace 国际专利分类1 = subinstr(国际专利分类1, "全部涉及:""", .)
replace 国际专利分类2 = subinstr(国际专利分类2, ":""", .)
replace 技术分支编号 = "8.2" if 技术分支编号 == "8.199999999999999"
replace 技术分支编号 = "9.2" if 技术分支编号 == "9.199999999999999"
replace 技术分支编号 = "9.3" if 技术分支编号 == "9.300000000000001"
ren 国际专利分类1 全部涉及
ren 国际专利分类2 部分涉及
compress 
foreach i of varlist _all {
 cap format `i' %10s 

drop 国际专利分类 
replace 技术分支编号 = subinstr(技术分支编号, " """, .)
save 专利分类号筛选标准, replace 

使用分类号进行专利筛选非常简单,这个之前就讲解过:

使用 Stata 提取和处理数字经济核心产业分类与国际专利分类参照关系表:https://rstata.duanshu.com/#/course/b2c71978336b4b39b69f05d6537d9d8f

全部涉及的就是指该分类下的所有专利都是绿色专利,部分涉及的则需要结合关键词进行筛选。

从该 pdf 文件中可以提取参考检索式部分:参考检索式.pdf参考检索式.xlsx 是转换并手动整理得到的结果,使用 Stata 处理下:

import excel using "参考检索式.xlsx"clear first 

*- 替换换行符 
gen temp = ustrregexs(0) if ustrregexm(参考关键词, "(\n)"
replace 参考关键词 = subinstr(参考关键词, temp, "", .)
drop temp 

gen temp = ustrregexs(0) if ustrregexm(IPC分类, "(\n)"
replace IPC分类 = subinstr(IPC分类, temp, "", .)
drop temp 

gen 绿色专利分类ID = _n 
order 绿色专利分类ID 

replace IPC分类 = subinstr(IPC分类, " """, .) 

foreach i of varlist _all {
 cap format `i' %20s 
}
replace 参考关键词 = subinstr(参考关键词, "  "" ", .)
replace 参考关键词 = subinstr(参考关键词, "  "" ", .)
save 参考检索式, replace 

检索式翻译成正则表达式

例如其中有一条:

参考关键词:(煤 OR COAL) (2N) (采 OR  矿 OR  井 OR EXCAVAT* OR MINE OR MINING OR PRODUCTING)
参考检索式:IPC=(E02D17/20 OR E02D19/06) AND TIABC=((煤 OR COAL) (2N) (采 OR 矿 OR 井 OR EXCAVAT* OR MINE OR MINING OR PRODUCTING))

Stata 中当然是不支持这种参考检索式的,所以我们需要把这些检索式一一翻译成正则表达式。这里有一些注意事项:

  1. IPC 表示 IPC 专利分类号;
  2. TIABC 表示标题+摘要;
  3. 检索式中的 N、W 和 S 是检索词的连接关系符号。N 没有顺序的限制,W 有顺序限制,S则是在同一句。1/2/3的数字表示两个检索词之间的隔的字数(小于等于该数字)。如检索“车座”(1N)“车把”,可以检索出“车座和车把”、“车把和车座”、“车座车把”、“车把车座”等将车座与车把间隔小于等于1个字并且没有顺序的语句,但检索“车座”(1W)“车把”仅能检索出“车座和车把”或“车座在车把”、“车座车把”等将车座与车把间隔小于等于1个字并且有顺序的语句。

因此例如这个翻译成 Stata 支持的正则表达式应该是:

:=> (煤 OR COAL) (2N) (采 OR 矿 OR 井 OR EXCAVAT* OR MINE OR MINING OR PRODUCTING)
:=> ustrregexm(text, "(煤|COAL)((.{0,2})|((?:\s*\b\w+\b\s*){0,2}))(采|矿|井|EXCAVAT\w*\b|MINE|MINING|PRODUCTING)|(采|矿|井|EXCAVAT\w*\b|MINE|MINING|PRODUCTING)((.{0,2})|((?:\s*\b\w+\b\s*){0,2}))(煤|COAL)")

在正则表达式中,,((.{0,2})|((?:\s*\b\w+\b\s*){0,2})) 表示 <= 两个字符或单词,由于这里使用了 2N,所以需要考虑两种情况。这里的一些字符含义:

  • () 的一种功能是把被括住的内容视为整体;
  • | 表示或者;
  • . 用于匹配任意字符;
  • {0,2} 表示 0~2 个;
  • \w+:匹配一个或多个单词字符。\w 代表任何字母数字字符(包括下划线),+表示前面的字符至少出现一次;
  • \s 用于匹配空格;
  • \b 用于匹配单词边界;
  • (?: ... ):这是一个非捕获组(non-capturing group),意味着匹配的内容不会被保存以供后续引用。它用于分组但不捕获匹配的内容。
  • 因此 (?:\s*\b\w+\b\s*){0,2}) 表示的是匹配 0~2 个单词(对于英文),(.{0,2}) 表示 0~2 个字符(对于汉字)。

因此 1N~5N 对应的正则表达式如下:

  • ((.{0,1})|((?:\s*\b\w+\b\s*){0,1}))
  • ((.{0,2})|((?:\s*\b\w+\b\s*){0,2}))
  • ((.{0,3})|((?:\s*\b\w+\b\s*){0,3}))
  • ((.{0,4})|((?:\s*\b\w+\b\s*){0,4}))
  • ((.{0,5})|((?:\s*\b\w+\b\s*){0,5}))

可以先测试下这个正则表达式是否有效:

clear all 
set obs 6
input str100 text 
"煤炭开采"
"煤采"
"煤炭开发开采"
"coal-mining"
开采煤炭
"co-mining"
compress 
replace text = strupper(text)
gen code = `"ustrregexm(text, "(煤|COAL)((.{0,2})|((?:\s*\b\w+\b\s*){0,2}))(采|矿|井|EXCAVAT\w*\b|MINE|MINING|PRODUCTING)|(采|矿|井|EXCAVAT\w*\b|MINE|MINING|PRODUCTING)((.{0,2})|((?:\s*\b\w+\b\s*){0,2}))(煤|COAL)")"'
gen res = `=code[_n]'

format code %10s 

list text res in 1/6 

*>     +--------------------+
*>     |         text   res |
*>     |--------------------|
*>  1. |     煤炭开采     1 |
*>  2. |         煤采     1 |
*>  3. | 煤炭开发开采     0 |
*>  4. |  COAL-MINING     1 |
*>  5. |     开采煤炭     1 |
*>     |--------------------|
*>  6. |    CO-MINING     0 |
*>     +--------------------+

可以看到煤炭开发开采不符合,因为“煤”和“采”之间有 4 个字,co-minig 不符合,是因为得有完整的 coal 采可以。

另外一个常用的表达可以分别用下面几种方式表达:

  • SAV* 表示 sav 开头的单词,其中 * 可以表达为:\w*\b
  • “H2” 表示特指氢气,如果直接使用 H2 可能会匹配到 H2O 之类的,因此应该使用类似这样的表达:([^a-zA-Z\d](H2)[^a-zA-Z\d]),也就是 H2 的前后都不应该有英文字符或者数字了;
  • (S) 表示前后内容在同一句话中,可以用 ([^.。!!;;]) 表示,也就是两个部分之间不应有表示句子结束的符号。

去除重复的就可以得到所有需要翻译的检索式了:

use 参考检索式, clear 
keep 参考关键词
duplicates drop 参考关键词, force 
drop if mi(参考关键词)

gsort 参考关键词 
save 待翻译正则表达式, replace 

export excel using 待翻译正则表达式.xlsx, replace firstrow(variables)

一共 71 个,工作量其实还挺大的。

N 字符的存在让这个工作变得非常难做。为此我编写了一个 R 脚本:

library(tidyverse)
read_csv("待转换.csv", col_names = F) %>% 
  mutate(X2 = map(X1, function(z){
    str <- str_match(z, "^\\((.*)\\)|$")[1,2]
    str_split_1(str, pattern = "\\s\\(\\dN\\)\\s") -> res
    str_match(str, pattern = "\\s\\(\\dN\\)\\s") -> splitstr
    
    apply(gtools::permutations(length(res), length(res)), 1function(x){
      res[x]
    }) %>% 
      t() %>% 
      apply(1function(x){
        paste0("(", paste0(x, collapse = splitstr), ")|")
      }) %>% 
      as_tibble()
  })) %>% 
  select(-X1) %>% 
  unnest(X2) %>% 
  mutate(value = str_remove_all(value, " ")) %>% 
  write_csv("待转换.csv", col_names = F, quote = "none"

这段代码可以把 待转换.csv 中的内容转换成需要的样子,例如如下内容:

((HYDROGEN* OR “H2” OR氢) (5N) (FUEL OR 燃料))|

运行上面的代码就会被转换成如下内容:

((HYDROGEN*OR“H2”OR氢)(5N)(FUELOR燃料))|
((FUELOR燃料)(5N)(HYDROGEN*OR“H2”OR氢))|

需要注意格式需要严格按照 ((...)(...N)(...))| 这样的结构。

待翻译正则表达式-翻译结果.xlsx 就是翻译得到的结果,待翻译正则表达式-翻译结果.dta 是读取成 dta 的结果:

import excel using "待翻译正则表达式-翻译结果.xlsx"clear first 
save "待翻译正则表达式-翻译结果"replace 

再把这个结果和去重前的合并:

use 参考检索式, clear 
drop 绿色专利分类ID 

replace IPC分类 = IPC分类[_n] + IPC分类[_n + 1] if mi(绿色技术分支[_n + 1]) & mi(参考关键词[_n + 1])
drop if mi(绿色技术分支) & mi(参考关键词)

compress 
foreach i of varlist _all {
 cap format `i' %10s 
}
gen 技术分支编号 = ustrregexs(0) if ustrregexm(绿色技术分支, "[\d.]*")
replace IPC分类 = subinstr(IPC分类, " """, .)

gen temp = ustrregexs(0) if ustrregexm(IPC分类, "\n")
replace IPC分类 = subinstr(IPC分类, temp, "", .)
drop temp 
drop 绿色技术分支 
order 技术分支编号
carryforward 技术分支编号, replace 
gen myid = _n 
order myid 
drop if mi(技术分支编号) 
merge m:1 参考关键词 using "待翻译正则表达式-翻译结果"
drop _m 
gsort myid 
drop 参考关键词 
split IPC分类, parse(",")
drop IPC分类 
gather IPC分类* 
drop if missing(value)
drop var 
save tempdata1, replace 

不过这里需要注意,有几个含有 NOT 条件的:

use tempdata1, clear 
keep if index(value, "NOT")

我们再把这些筛选条件加到正则表达式里面:


use tempdata1, clear
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "C01B3/04")"' if value == "C01B3/00(NOT:C01B3/04)"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "F03B13/02", "F03B13/04", "F03B13/12")"' if value == "F03B13/00(NOT:F03B13/02ORF03B13/04ORF03B13/12)"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "E02B9/08")"' if value == "E02B9/00(NOT:E02B9/08)"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "F03B17/04")"' if value == "F03B17/02(NOT:F03B17/04)"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "C10G1/10")"' if value == "C10G1/00(NOT:C10G1/10)"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "C10L3/02")"' if value == "C10L3/00(NOT:C10L3/02"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "G01R31/01")"' if value == "G01R31/00(NOTG01R31/01"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "B01D53/84")"' if value == "B01D53/34(NOT:B01D53/84)"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "C09K23/50")"' if value == "(C09K23/00NOTC09K23/50)"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "B01F17/50")"' if value == "(B01F17/00NOTB01F17/50)"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "C08L101/16")"' if value == "(C08L101/00NOTC08L101/16)"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "B60K1/04")"' if value == "B60K1/00NOTB60K1/04"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "B60K6/28", "B60K6/30")"' if value == "B60K6/00NOT(B60K6/28ORB60K6/30)"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "B60W10/26")"' if value == "B60W10/00NOTB60W10/26"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "B60W20/16")"' if value == "B60W20/00NOTB60W20/16"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "C05G3/02")"' if value == "(C05G3/00NOTC05G3/02)"
replace 正则表达式 = 正则表达式 + "&" + `"!index(分类号, "C05G3/60")"' if value == "(C05G3/00NOTC05G3/60)"


replace value = "C01B3/00" if value == "C01B3/00(NOT:C01B3/04)"
replace value = "F03B13/00" if value == "F03B13/00(NOT:F03B13/02ORF03B13/04ORF03B13/12)"
replace value = "E02B9/00" if value == "E02B9/00(NOT:E02B9/08)"
replace value = "F03B17/02" if value == "F03B17/02(NOT:F03B17/04)"
replace value = "C10G1/00" if value == "C10G1/00(NOT:C10G1/10)"
replace value = "C10L3/00" if value == "C10L3/00(NOT:C10L3/02"
replace value = "G01R31/00" if value == "G01R31/00(NOTG01R31/01"
replace value = "B01D53/34" if value == "B01D53/34(NOT:B01D53/84)"
replace value = "C09K23/00" if value == "(C09K23/00NOTC09K23/50)"
replace value = "B01F17/00" if value == "(B01F17/00NOTB01F17/50)"
replace value = "C08L101/00" if value == "(C08L101/00NOTC08L101/16)"
replace value = "B60K1/00" if value == "B60K1/00NOTB60K1/04"
replace value = "B60K6/00" if value == "B60K6/00NOT(B60K6/28ORB60K6/30)"
replace value = "B60W10/00" if value == "B60W10/00NOTB60W10/26"
replace value = "B60W20/00" if value == "B60W20/00NOTB60W20/16"
replace value = "C05G3/00" if value == "(C05G3/00NOTC05G3/02)"
replace value = "C05G3/00" if value == "(C05G3/00NOTC05G3/60)"

然后还有一个注意事项,我们之前提到过 IPC 分类号中的大组和小组看似是包含关系,实际上是对应关系,这个可以参考这个课程:

使用 R 语言爬取处理 WIPO 绿色专利分类数据:https://rstata.duanshu.com/#/brief/course/6edd7ed2f3284915b2c916ead3fbfd10

但是根据知识产权局的这个回复来看:

筛选标准里面的大组和小组实际上是看作包含关系,例如 C01B3/00(NOT:C01B3/04) 表示的是所有 IPC 分类号开头是 C01B3 的,但是 C01B3/04 除外。

也就是说按照知识产权局的意思,大组的分类包含其下的小组,所以把所有的 /00 去除:

replace value = subinstr(value, "/00""", .) 
ren value IPC 
save 参考关键词整理结果, replace 

筛选逻辑

我的想法是按照下面四个步骤筛选:

  1. 首先从总专利里面筛选全部涉及和部分涉及分类下的所有专利。先缩小范围,减少数据的大小;
  2. 筛选全部涉及的部分;
  3. 筛选部分涉及的;
  4. 合并所有筛选的结果。

筛选所有符合分类号筛选条件的专利

附件中我准备了一份 2010 年的专利申请数据:2010年专利申请数据.dta

use 2010年专利申请数据.dta, clear 

下面我们根据分类号进行筛选。

首先我们需要删除设计专利、保留关键变量(减少数据大小)以及拆分分类号。

在之前的课程「使用 Stata 进行绿色专利的筛选」中我介绍过 split + gather 以及 split + 循环 append 的方法:

使用 Stata 进行绿色专利的筛选:https://rstata.duanshu.com/#/brief/course/2fd6838527754c94a3f5ccb0e3ba7be1

在课程「使用 Stata 处理专利数据的分类号」中我也介绍了使用 Mata 的方法:

名师讲堂|使用 Stata 处理专利数据的分类号:https://rstata.duanshu.com/#/brief/course/1cfb2e8e8e5f4716959fc78bbaf6d446

这里我们使用 Mata 方法:

*- 2010 年专利数据
use 2010年专利申请数据, clear 
drop if !index(IPC, "/")
keep ipzlid IPC 
ren IPC 分类号

*- 排好序
gsort ipzlid  
*- 统计可拆分的数量:_gipc_count.ado
egen n = ipc_count(分类号), parse(;)

*- 把数据读入 mata 中处理:
mata:
mata clear 
// 把分类号数据读入 mata
v1 = st_sdata(., "分类号"

// 转换成行向量 
v2 = rowshape(v1, cols(v1))

// 连接起来 
v3 = invtokens(v2, ";")

// 使用分号拆分
v4 = ustrsplit(v3, ";")
// 转换成列向量
v5 = colshape(v4, rows(v4))
end 

*- 回到 Stata 中
expand n 

*- ipzlid 的顺序不能变
gsort ipzlid  

*- 从 mata 的 v5 再创建变量
mata:
stata("cap drop newvar")
st_addvar("strL""newvar")
st_sstore(., "newvar", v5)
end 

drop 分类号 n 
ren newvar IPC 

replace IPC = ustrregexs(1) if ustrregexm(IPC, "(.*)\(")
save "IPC分类号拆分结果"replace 
list in 1/10 

*>     +------------------------+
*>     |     ipzlid         IPC |
*>     |------------------------|
*>  1. | 2010000001   A47J37/08 |
*>  2. | 2010000002   A47J37/08 |
*>  3. | 2010000003   A47J37/10 |
*>  4. | 2010000004   A47J37/12 |
*>  5. | 2010000005   A47J37/12 |
*>     |------------------------|
*>  6. | 2010000005    A21B5/08 |
*>  7. | 2010000006   A47J37/12 |
*>  8. | 2010000007   A47J43/07 |
*>  9. | 2010000008   A47J47/08 |
*> 10. | 2010000009   A47J47/16 |
*>     +------------------------+

然后就可以根据分类号条件进行筛选了。

我们把分类号筛选条件按照长度进行拆分:

use 参考关键词整理结果, clear 
gen len = strlen(IPC)
tab len 
gsort len 
cap mkdir "res1"
forval l = 3/12 {
 preserve 
 keep if len == `l'
 save res1/`l'replace 
 restore 

循环匹配筛选:

cap mkdir "res2"
use IPC分类号拆分结果.dta, clear 
*- strL 格式的变量不能用来进行 joinby,所以要 recast 下:
recast str12 IPC, force 
gen len = strlen(IPC)
replace IPC = ustrregexs(0) if ustrregexm(IPC, ".{5,6}/.{2}") & len > 12 
replace len = strlen(IPC)
tab len 
drop len 

forval l = 3/12 {
 preserve 
 replace IPC = substr(IPC, 1, `l')
 joinby IPC using res1/`l'
 save res2/`l'replace 
 restore 


*- 合并
use res2/3, clear 
forval l = 4/12 {
 append using res2/`l' 
}
count if 正则表达式 == "1==1"
drop len IPC 
duplicates drop ipzlid myid, force 
save 初步筛选结果, replace 

这样就完成了初步筛选。

筛选符合关键词条件的专利

再把标题和关键词信息合并进来:

use 初步筛选结果, clear 
tostring ipzlid, replace format(%16.0f)
merge m:1 ipzlid using 2010年专利申请数据.dta
drop if _m == 2
drop _m 
egen expgroup = group(正则表达式)
codebook expgroup 

*> ----------------------------------------------------------------------------------
*> expgroup                                                         group(正则表达式)
*> ----------------------------------------------------------------------------------
*> 
*>                   Type: Numeric (float)
*> 
*>                  Range: [1,79]                        Units: 1
*>          Unique values: 79                        Missing .: 0/250,983
*> 
*>                   Mean: 37.4997
*>              Std. dev.: 22.5094
*> 
*>            Percentiles:     10%       25%       50%       75%       90%
*>                               3        19        37        53        66

replace 标题 = strupper(标题)
replace 摘要 = strupper(摘要)
replace 标题 = subinstr(标题, "  """, .)
replace 摘要 = subinstr(摘要, "  """, .)
gen text = 标题 + " " + 摘要
drop 标题 摘要 
ren IPC 分类号
save 初步筛选结果2, replace 

循环进行筛选:

cap mkdir "res3" 
use 初步筛选结果2, clear 
forval i = 1/79 {
 di "`i'"
 preserve 
 keep if expgroup == `i'
 qui cap {
  keep if `=正则表达式[1]' 
  save res3/`i'replace 
 }
 restore 
}

对于那些没有得到任何结果的表达式要进行仔细检查,例如这里发现 10 号表达式有问题:

replace 正则表达式 = `"ustrregexm(text, "((((煤|COAL)((.{0,2})|((?:\s*\b\w+\b\s*){0,2}))(采|矿|井|EXCAVAT\w*\b|MINE|MINING|PRODUCTING))|((采|矿|井|EXCAVAT\w*\b|MINE|MINING|PRODUCTING)((.{0,2})|((?:\s*\b\w+\b\s*){0,2}))(煤|COAL)))&(节能|节碳|节约|绿色|低碳|SAV\w*\b|ENERGY|ECONOMIZ\w*\b|RETRENCH\w*\b|RECYCL\w*\b|CLEAN\w*\b|SUBSTITUT\w*\b|ALTERNATIVE|GREEN|(减排|减碳|((LOW\w*\b|REDUC\w*\b)((.{0,2})|((?:\s*\b\w+\b\s*){0,2}))CARBON)|(CARBON((.{0,2})|((?:\s*\b\w+\b\s*){0,2}))(LOW\w*\b|REDUC\w*\b)))))")"' if 正则表达式 == `"ustrregexm(text, "(((煤|COAL)((.{0,2})|((?:\s*\b\w+\b\s*){0,2}))(采|矿|井|EXCAVAT\w*\b|MINE|MINING|PRODUCTING))|"'

使用修正后的结果再运行:

use 初步筛选结果2, clear 
replace 正则表达式 = `"ustrregexm(text, "((((煤|COAL)((.{0,2})|((?:\s*\b\w+\b\s*){0,2}))(采|矿|井|EXCAVAT\w*\b|MINE|MINING|PRODUCTING))|((采|矿|井|EXCAVAT\w*\b|MINE|MINING|PRODUCTING)((.{0,2})|((?:\s*\b\w+\b\s*){0,2}))(煤|COAL)))&(节能|节碳|节约|绿色|低碳|SAV\w*\b|ENERGY|ECONOMIZ\w*\b|RETRENCH\w*\b|RECYCL\w*\b|CLEAN\w*\b|SUBSTITUT\w*\b|ALTERNATIVE|GREEN|(减排|减碳|((LOW\w*\b|REDUC\w*\b)((.{0,2})|((?:\s*\b\w+\b\s*){0,2}))CARBON)|(CARBON((.{0,2})|((?:\s*\b\w+\b\s*){0,2}))(LOW\w*\b|REDUC\w*\b)))))")"' if 正则表达式 == `"ustrregexm(text, "(((煤|COAL)((.{0,2})|((?:\s*\b\w+\b\s*){0,2}))(采|矿|井|EXCAVAT\w*\b|MINE|MINING|PRODUCTING))|"'
keep if expgroup == 10
keep if `=正则表达式[1]' 
save res3/10, replace 

不过这里还是没有得到结果。

合并所有的:

use res3/1, clear 
forval y = 2/79 {
 append using res3/`y'
}
keep ipzlid 技术分支编号 
duplicates drop _all, force 
save 2010绿色专利筛选结果, replace 

list in 1/10

*>     +----------------------+
*>     |     ipzlid   技术~号 |
*>     |----------------------|
*>  1. | 2010000271     8.2.2 |
*>  2. | 2010000272     8.2.2 |
*>  3. | 2010000273     8.2.2 |
*>  4. | 2010000274     8.2.2 |
*>  5. | 2010000275     8.2.2 |
*>     |----------------------|
*>  6. | 2010000276     8.2.2 |
*>  7. | 2010000278     8.2.2 |
*>  8. | 2010000279     8.2.2 |
*>  9. | 2010000280     8.2.2 |
*> 10. | 2010000281     8.2.2 |
*>     +----------------------+

这样我们就完成了该年的绿色专利筛选。

最后我们再统计各个类别的申请占比:

use 专利分类号筛选标准.dta, clear 
keep if strlen(技术分支编号) == 1 
keep 技术分支*
save classdf, replace 

use 2010绿色专利筛选结果, clear 
replace 技术分支编号 = substr(技术分支编号, 1, 1)
merge m:1 技术分支编号 using classdf 
contract 技术分支名称 
gr pie _freq, over(技术分支名称) ///
 plabel(_all percent, format(%6.2f)) ///
 ti("2010 年绿色技术专利各类别申请占比"///
 subti("数据处理:微信公众号 RStata"///
 caption("数据来源:国家知识产权局"

gr export pic7.png, width(4800) replace 

不过需要注意的是,专利数据中同时包含了申请和授权信息,因此统计数量前需要先去重,这个可以阅读专利数据的介绍:

1985~2024 年专利申请与授权数据(版本 3,含申请人所处的省市区县):https://rstata.duanshu.com/#/brief/course/2397451274c546d3a36e156ffc865988

这里由于没有公开公告号变量,所以没有这么做。

如何参加课程?

购买 RStata 名师讲堂会员都可以参加这个课程啦!

详情可阅读这篇推文:数据处理、图表绘制、效率分析与计量经济学如何学习~,更多关于 RStata 培训班的信息可添加微信号 r_stata 咨询(上图中有二维码)。

会员购买:从首页的会员卡专区即可查看和购买会员卡 https://rstata.duanshu.com/#/card/list/

课程主页(点击文末的阅读原文即可跳转):

https://rstata.duanshu.com/#/brief/course/66607ec05c3748699883f5e834682125


RStata
一起学习 R 语言和 Stata 吧!
 最新文章