为了让大家更好地理解本文内容,欢迎各位名师讲堂会员参加明晚 8 点的直播课:「使用 Stata 计算专利知识宽度:Mata 方法」。
在之前的课程中我们讲解过如何使用 Stata 编程计算专利知识宽度:
使用 Stata 编程计算企业专利知识宽度:https://rstata.duanshu.com/#/brief/course/7a0978798b6244779e13401ee68f3761 使用 Stata 计算专利技术空间相似度、企业层面的知识宽度、新技术空间专利申请及IPC号新增数:https://rstata.duanshu.com/#/brief/course/535f9284c31d47c2861b8cd1384394d0
今天我们再介绍一下如何使用 Mata 加快计算速度,以及编写用于计算专利知识宽度的 egen 函数。
本次课程将会讲解下面三篇文献中提供的专利知识宽度计算方法:
创新追赶战略抑制了中国专利质量么_张杰.pdf 网络基础设施建设、信息可得性与企业创新边界_沈坤荣.pdf 专利质量对企业出口竞争力的影响机制_基于知识宽度视角的探究_李宏.pdf
附件中也提供了文献的 pdf 文件。
分类号方法(大组):张杰、郑文平(2020,经济研究)
第一种是张杰、郑文平(2020,经济研究)中介绍的方法:
采取大组层面(使用分类号提取)的赫芬达尔—赫希曼指数(HH)的逻辑思路对其进行加权,企业专利知识宽度的具体计算方法为:
其中, 表示专利分类号中各大组分类所占比重。可以看出,越大,各个大组层面的专利分类号之间的差异越大,即表明企业创造专利所运用的知识宽度越大,其专利质量可能就表现为越高。
经过上面的计算可以得到专利层面的知识宽度信息,然后可以汇总到企业层面,具体来说又分为两种,均值法和中位数方法。
在之前的课程中我们介绍过使用 ado 编程的方法:
*- 之前的方法
use data, clear
ren 分类号 IPC
*- 删除设计专利
drop if !index(IPC, "/")
split IPC, parse(";")
ren IPC 分类号
*- ssc install tidy
gather IPC*
drop if value == ""
save temp.dta, replace
use temp.dta, clear
foreach i of varlist _all {
cap format `i' %10s
}
gen 大组 = ustrregexs(1) if ustrregexm(value, "(.*)/(.*)")
*- 计算每个专利的分类号数量
bysort newzlid: egen z1 = count(newzlid)
bysort newzlid 大组: egen z2 = count(newzlid)
bysort newzlid 大组: keep if _n == _N
gen double z3 = z2 / z1
*- 计算 z3 的和
bysort newzlid: egen z4 = sum(z3^2)
gen patent_knowledge = 1 - z4
drop z*
bysort newzlid: keep if _n == _N
gsort newzlid
drop 大组 var value
ren 分类号 IPC
ren patent_knowledge 旧方法计算的专利知识宽度
这里使用了 split 和 gather,对于观测值较多的数据,这种方法是非常耗时的。下面使用 mata 方法计算:
*- 使用 Mata 提升速度
mata:
// uniquerow() 函数的功能是对列向量进行排序去重
string vector uniquerow(string vector x) {
b = uniqrows(rowshape(x, cols(x)))
return(colshape(b, rows(b)))
}
// 读取 IPC 变量
v = st_sdata(., "IPC")
// ipccountres 用于存储计算结果
ipccountres = J(rows(v), 1, .)
// 循环所有的分类号
for(z=1;z<=rows(v);z++){
// 分类号之间使用 ; 分开
a = ustrsplit(v[z], ";")
aa = J(1, cols(a), "")
for(t=1;t<=cols(a);t++){
// 提取每个分类号的大组
b = ustrsplit(a[t], "/")
aa[t] = b[1]
}
// bb 是所有互不相同的大组
bb = uniquerow(aa)
// cc 是用来存储每个大组的数量
cc = J(1, cols(bb), 0)
// 循环统计每个大组的数量
for(i=1;i<=cols(bb);i++) {
for(j=1;j<=cols(aa);j++) {
if(aa[j]==bb[i]) {
cc[i] = cc[i] + 1
}
}
}
// 计算专利知识宽度
ipccountres[z] = 1 - sum((cc/sum(cc)):^2)
}
// 根据 ipccountres 创建新变量
stata("cap drop newufvar")
st_addvar("double", "newufvar")
st_store(., "newufvar", ipccountres)
end
*- 重命名
ren newufvar Mata方法计算的专利知识宽度
为了方便使用,我把这些代码封装成了一个 egen 函数:_gipc_pk.ado
egen egen函数计算的专利知识宽度 = ipc_pk(IPC), parse(;)
这样原来需要几十行代码,数十分钟才能运行完的程序,现在只需要一行代码、数秒钟即可。
分类号方法(大类):沈坤荣(2023,工业经济)
沈坤荣(2023,工业经济)中计算专利知识宽度的方法和上面介绍的略有不同:
所以我们可以先提取分类号的前 3 位(也就是大类,而上面是使用大组信息):
egen ipc1_3 = ipc_sub(IPC), parse(;) from(1) to(3)
使用 ipc_sub() 函数需要把
_gipc_sub.ado
文件放在工作目录下,关于该函数的编写和使用,可以学习之前的课程:使用 Stata 处理专利数据的分类号:https://rstata.duanshu.com/#/brief/course/1cfb2e8e8e5f4716959fc78bbaf6d446
然后就可以使用 ipc_pk() 计算专利知识宽度了:
egen pk1_3 = ipc_pk(ipc1_3), parse(;)
主分类号方法:李宏、王云廷等(2021,世界经济研究)
李宏、王云廷等(2021,世界经济研究)给出了另外一种计算专利知识宽度的方法:
其中, 为企业 截止 年在 大组下发明与实用新型申请专利的累计数目, 为企业 截止 年在全部大组下申请专利的累计数目。 的值越大,说明企业专利的知识宽度越大,专利质量越高。
这样直接就可以得到企业-年份层面的专利质量数据了。
特别需要注意的是,这里计算 t 年的知识宽度是使用 截止 t 年的所有专利。
首先简单把数据整理下:
clear all
use data2, clear
ren 分类号 IPC
*- 去除重复的
replace 公开公告号 = subinstr(公开公告号, "A", "", .)
replace 公开公告号 = subinstr(公开公告号, "B", "", .)
replace 公开公告号 = subinstr(公开公告号, "U", "", .)
replace 公开公告号 = subinstr(公开公告号, "S", "", .)
*- 使用 duplicates drop 去除重复的
duplicates drop 股票代码 公开公告号, force
* 删除设计专利
drop if !index(IPC, "/")
*- 分类号的第一个是主分类号,可以使用:_gipc_sub0.ado
egen IPC_main = ipc_sub0(IPC), parse(;) choose(1)
*- 去除结尾的日期
replace IPC_main = ustrregexs(1) if ustrregexm(IPC_main, "(.*)\(")
compress
drop 公开公告号
save data2a, replace
由于这里并不需要进行 split 和 gather,所以直接使用 Stata 计算也是很快的:
use data2a, clear
gen 大组 = ustrregexs(1) if ustrregexm(IPC_main, "(.*)/(.*)")
*- 计算 Zimt
bysort 股票代码 年份 大组: egen Zimt = count(newzlid)
*- egen + sum(): 分组求和 3 3 3
*- gen/replace + sum(): 分组累加 1 2 3
bysort 股票代码 年份 大组: keep if _n == _N
bysort 股票代码 大组 (年份): replace Zimt = sum(Zimt)
save Zimt, replace
*- 计算 Zit
use data2a, clear
bysort 股票代码 年份: egen Zit = count(newzlid)
bysort 股票代码 年份: keep if _n == _N
*- 注意这里是截止 t 年,并不是每年的
bysort 股票代码 (年份): replace Zit = sum(Zit)
save Zit, replace
*- 合并两部分的数据
use Zimt, clear
keep 股票代码 年份 Zimt
merge m:1 年份 股票代码 using Zit
drop _m
gen z1 = Zimt / Zit
gen z2 = z1 ^ 2
bysort 股票代码 年份: egen z3 = sum(z2)
gen patent_knowledge = 1 - z3
drop Z* z*
bysort 股票代码 年份: keep if _n == _N
keep 股票代码 年份 patent_knowledge
ren patent_knowledge 公司专利知识宽度
save "公司专利知识宽度", replace
list in 1/10
*> +----------------------------+
*> | 股票代码 年份 公司~度 |
*> |----------------------------|
*> 1. | 000001 2003 0 |
*> 2. | 000001 2010 .75 |
*> 3. | 000001 2013 .875 |
*> 4. | 000001 2016 .75 |
*> 5. | 000001 2017 .8979592 |
*> |----------------------------|
*> 6. | 000001 2018 .8888889 |
*> 7. | 000001 2019 .8933089 |
*> 8. | 000001 2020 .906989 |
*> 9. | 000001 2021 .8990105 |
*> 10. | 000063 1998 .75 |
*> +----------------------------+
关于这种方法的实现,我也尝试使用 Mata 编写了一些程序,不过速度也都很慢,还不如上面的代码。主要是字符串循环累加很费时间。所以还要使用 Mata 了。
直播信息
为了让大家更好地理解本文内容,欢迎各位名师讲堂会员参加明晚 8 点的直播课:「使用 Stata 计算专利知识宽度:Mata 方法」。
直播地址:腾讯会议(需要报名 RStata 培训班参加) 讲义材料:需要购买 RStata 名师讲堂会员,详情可阅读:一起来学习 R 语言和 Stata 啦!学习过程中遇到的问题也可以随时提问!
更多关于 RStata 会员的更多信息可添加微信号 r_stata 咨询:
附件下载(点击文末的阅读原文即可跳转):
https://rstata.duanshu.com/#/brief/course/13e8ca0a5b334949982a102aeefcf7c1