有问题,不要怕!点击推文底部“阅读原文”下载爬虫俱乐部用户问题登记表并按要求填写后发送至邮箱statatraining@163.com,我们会及时为您解答哟~
喜大普奔~爬虫俱乐部的github主站正式上线了!我们的网站地址是:https://stata-club.github.io,粉丝们可以通过该网站访问过去的推文哟~
Part
1
在之前的推文《moss命令、正则表达式与简单的文本分析》中,我们提到过怎样利用moss命令提取英文姓氏。那么,如果不用moss命 令,我们可以怎么做呢?今天爬虫小编就带着大家来看一下我们如何以另一种帅气的姿势get到英文名中的姓氏。通过之前的推文我们知道英文名的姓氏有个这么 一个特征:一个大写的英文字母加上数个小写的英文字母。找到了要提取部分的特征,如何提取就是我们需要解决的重点问题。
首先,我们将一些需要处理的数据导入stata中。
clear
input str509 author
"O. B. Tofler and T. L. Woodings"
"S. Hodgins, S. Lovenhag, M. Rehn and K. W. Nilsson"
"G. E. Vaillant"
"W. A. Pridemore, S. Tomkins, K. Eckhardt, N. Kiryanov and L. Saburova"
"W. Zheng, J. K. Mclaughlin, G. Gridley, E. Bjelke, L. M. Schuman, D. T. Silverman, S. Wacholder, H. T. Chien, W. J. Blot and J. F. Fraumeni"
"H. M. Pettinati, A. A. Sugerman, N. Didonato and H. S. Maurer"
"A. M. Gallagher, J. M. Savage, L. J. Murray, G. D. Smith, I. S. Young, P. J. Robson, C. E. Neville, G. Cran, J. J. Strain and C. A. Boreham"
"G. E. Vaillant"
"R. J. Goldberg, C. M. Burchfiel, D. M. Reed, G. Wergowske and D. Chiu"
"E. M. Smith and C. R. Cloninger"
end
如下图所示:
接下来,爬虫酱要划重点啦!我们在这里会给大家介绍两种方法,仅供大家参考。
Part
2
方法一:
通常大家遇到这个问题的时候,第一步是这样做的:
gen v1 = ustrregexs(1) if ustrregexm(author,"([A-Z][a-z]+)")
结果如上图所示:我们提取出了每个观测值的第一个姓氏,那么如何提取第二个的姓氏呢?
我们的方法是用函数ustrregexrf()把每个观测值的第一个姓氏删除掉,即:
replace author = ustrregexrf(author,"[A-Z][a-z]+","")
接 着再进行第二次提取,以此类推。这样反复提取,最终把所有的姓氏都提取出来了。但是问题是,当姓氏特别多的时候,我们就需要写一个循环,去执行上述操作。 因为我们并不知道观测值中最多有多少个姓氏,为了确保所有的姓氏都被提取出来,我们让循环执行20次,即生成20个变量,相应的对姓氏提取20次,程序如 下:
forvalue i = 1(1)20 {
gen v`i' = ustrregexs(1) if ustrregexm(author,"([A-Z][a-z]+)")
replace author = ustrregexrf(author,"[A-Z][a-z]+","")
}
那么,问题又来了,变量author的所有观测值中最多有10个姓氏。V11-v20都没有提取出任何内容。怎么删除它们呢?
我们先来看一下需要删除的变量的特征,那就是它们从第一行到最后一行都为空,那么如果某个变量的所有观测值加起来仍然等于空,就把这个变量删除掉,并终止循环。我们可以输入以下命令:
local s = ""
forvalue j = 1(1)`=_N' {
local s = "`s'" + v`i'[`j']
}
if "`s'" == "" {
drop v`i'
continue ,break
}
我 们来解释一下上述程序,即我们首先定义一个空的局部宏,然后我们将某个变量第一行一直到最后一行的数据重复叠加后将其赋值给宏s。如果这时宏s仍然为空, 也就是说该变量从第一行到最后一行全部为空,这说明每一行观测值都没有提取出来信息,这时删除变量的同时,终止循环。整个过程的程序整合在一起如下:
forvalue i = 1(1)20 {
gen v`i' = ustrregexs(1) if ustrregexm(author,"([A-Z][a-z]+)")
local s = ""
forvalue j = 1(1)`=_N' {
local s = "`s'" + v`i'[`j']
}
if "`s'" == "" {
drop v`i'
continue ,break
}
replace author = ustrregexrf(author,"[A-Z][a-z]+","")
}
我们运行以后看一下最终结果:
我们最终得到10个变量,将前面的数据中姓氏全部提取出来,且没有剩下多余的空变量。
Part
3
方法二:
第一种方法大家是不是看起来很费劲很麻烦,感觉看完头大?爬虫君再来跟大家说一种简单易行的办法,不过前提是我们需要了解一个函数——count。
为了让大家迅速了解这个函数,我们举个例子说明一下,在stata中输入以下命令:
sysuse auto, clear
count if price < 10000
结果如下:
结果显示64,那么这结果是什么意思呢?我们的命令又是什么意思呢?这里count if 是计算满足某种条件的数据的总计。也就是说,满足价格小于10000的数据总共有64个。这个命令有个返回值,我们来看一下他的返回值是什么样的,输入命令:
return list
也就是说,函数count的返回值为r(N),它表示符合某个条件的观测值的数量。这个返回值我们可以在后边调用。
现在来思考一下,我们是不是可以先用count if 来计算每个变量中的空值个数,当空观测值的数量等于总观测值的数量时,说明每一个观测值都没有提取出来姓氏,这时删除该变量,跳出循环。我们可以写出如下程序:
count if v`i' == ""
if `r(N)' == `=_N' {
drop v`i'
continue ,break
}
当其返回值为观测值的总数,在这里为10时,我们就可以判断出该变量是多余的可以删掉,同时终止循环。再加上前面所说的提取数据的程序,得到最终程序如下:
forvalue i = 1(1)20 {
gen v`i' = ustrregexs(1) if ustrregexm(author,"([A-Z][a-z]+)")
count if v`i' == ""
if `r(N)' == `=_N' {
drop v`i'
continue ,break
}
replace author = ustrregexrf(author,"[A-Z][a-z]+","")
}
我们再来看一下最终结果:
与方法一相同,我们都能得到全部的姓氏,并且删除了多余的变量。
怎么样,今天的方法大家都get到了吗?
注:此推文中的图片及封面均来源于网络!如有雷同纯属巧合!
以上就是今天给大家分享的内容了,说得好就赏个铜板呗!有钱的捧个钱场,有人的捧个人场~。另外,我们开通了苹果手机打赏通道,只要扫描下方的二维码,就可以打赏啦!
应广大粉丝要求,爬虫俱乐部的推文公众号打赏功能可以开发票啦,累计打赏超过1000元我们即可给您开具发票,发票类别为“咨询费”。用心做事,只为做您更贴心的小爬虫。第一批发票已经寄到各位小主的手中,大家快来给小爬虫打赏呀~
文字编辑/王 悦
技术总编/刘贝贝
往期推文推荐:
5.爬虫俱乐部又出新命令了——wordconvert转换你的word文件
关于我们
微信公众号“爬虫俱乐部”分享实用的stata命令,欢迎转载、打赏。爬虫俱乐部是由李春涛教授领导下的研究生及本科生组成的大数据分析和数据挖掘团队。
此外,欢迎大家踊跃投稿,介绍一些关于stata的数据处理和分析技巧。
投稿邮箱:statatraining@163.com
投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿”+“推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到关于stata分析数据的问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。
欢迎关注爬虫俱乐部
微信扫一扫
关注该公众号