名师讲堂|使用 Stata 计算专利知识宽度:Mata 方法

教育   教育   2024-12-16 14:34   安徽  

为了让大家更好地理解本文内容,欢迎各位名师讲堂会员参加明晚 8 点的直播课:「使用 Stata 计算专利知识宽度:Mata 方法」


在之前的课程中我们讲解过如何使用 Stata 编程计算专利知识宽度:

  1. 使用 Stata 编程计算企业专利知识宽度:https://rstata.duanshu.com/#/brief/course/7a0978798b6244779e13401ee68f3761
  2. 使用 Stata 计算专利技术空间相似度、企业层面的知识宽度、新技术空间专利申请及IPC号新增数:https://rstata.duanshu.com/#/brief/course/535f9284c31d47c2861b8cd1384394d0

今天我们再介绍一下如何使用 Mata 加快计算速度,以及编写用于计算专利知识宽度的 egen 函数。

本次课程将会讲解下面三篇文献中提供的专利知识宽度计算方法:

  1. 创新追赶战略抑制了中国专利质量么_张杰.pdf
  2. 网络基础设施建设、信息可得性与企业创新边界_沈坤荣.pdf
  3. 专利质量对企业出口竞争力的影响机制_基于知识宽度视角的探究_李宏.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 方法」

  1. 直播地址:腾讯会议(需要报名 RStata 培训班参加)
  2. 讲义材料:需要购买 RStata 名师讲堂会员,详情可阅读:一起来学习 R 语言和 Stata 啦!学习过程中遇到的问题也可以随时提问!

更多关于 RStata 会员的更多信息可添加微信号 r_stata 咨询:

附件下载(点击文末的阅读原文即可跳转):

https://rstata.duanshu.com/#/brief/course/13e8ca0a5b334949982a102aeefcf7c1


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