楼主: professionaldu
3610 10

[其他] 关于寻找并合并comma delimited data里面因为多余的逗号被分开的变量值 [推广有奖]

  • 0关注
  • 0粉丝

小学生

0%

还不是VIP/贵宾

-

威望
0
论坛币
25 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
81 点
帖子
6
精华
0
在线时间
1 小时
注册时间
2007-12-7
最后登录
2014-9-19

楼主
professionaldu 发表于 2011-10-12 11:36:19 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
问题是这样的,因为数据源是比较原始的comma delimited data,于是多余的逗号把本来两个变量的值放到了n个里面去,现在要找出来哪些是分别这两个变量的并把值赋回去
两个变量分别是name和address,name在前,address紧跟在后
name不知道被分成了多少块,address没有多余的逗号,所以在一个ob里面,但是不知道在哪个var那一竖行(v3-v10),并且address如果没有具体的地址将会出现00000,所以我写的是这样的:
foreach n of numlist 10/3 { ;  /*这个n是global的么?里面的内循环的foreach认么?*/  capture drop v`n' ;
  if !_rc { ;
    gen address = v`n';
        replace address = "N/A" if address=="00000";
        
    gen name = "";
      foreach m of numlist `n-1'/3 { ;
          replace name=name + v`m' ;
      } ;
    break ;
   } ;
  else continue ;
} ;



基本的东西我觉得应该没有什么问题,但是后面要用name的时候,提示name这个variable是undefined,于是我就纳了个闷了,高手瞅一眼指导一下(难道在循环里面生成的变量不是全局变量?但这个不是只有宏才该有的问题么。。。)
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:delimit Limited limit Comm Data address 数据源

沙发
jzhyue 发表于 2011-10-12 14:43:50
gen nam=v3+","+v4+","+v5+","+v6+","+v7+","+v8+","+v9+","+v10
replace nam=subinstr(nam,",00000","",.)
replace nam=reverse(nam)
replace nam=subinstr(nam,",","@",1)
replace nam=reverse(nam)
split nam,gen(name) p(@)
ren name1 name
ren name2 adrress

藤椅
jzhyue 发表于 2011-10-12 20:43:30
gen name=v3+","+v4+","+v5+","+v6+","+v7+","+v8+","+v9+","+v10
replace name=subinstr(name,",00000","",.)
egen address=ends(name),p(,) l
replace name=subinstr(name,","+address,"",.)

板凳
professionaldu 发表于 2011-10-14 03:48:14
jzhyue 发表于 2011-10-12 20:43
gen name=v3+","+v4+","+v5+","+v6+","+v7+","+v8+","+v9+","+v10
replace name=subinstr(name,",00000"," ...
谢谢
这个程序是个子程序,有一个母程序导入,由于有多个数据库,每个导入时生成的变量数不同,所以要先检查一共有多少个变量,所以我才拿capture来检测v`n'是否存在(当然,上面那个写错了,应该是capture confirm v v`n')
然后知道最大的变量是几之后还得检查变量是否为空,
并且,address后面依然可能有空的变量,如果直接用你的句子就可能最后有几个逗号。
所以在用v3+v4+v5....+v`n'之前还要判断这个变量是否为空
我改了一下成下面的样子,但是报错说varlist not allowed,r(101);我不知道多重循环改怎么弄,麻烦你帮忙看看

gen str40 name="";

foreach n of numlist 10/4 {
  capture confirm v v`n';
  if _rc==0 {
    foreach m of numlist `n'/3{
    replace name=name+v`m'+",";
        }
  }
  else continue ;
}

replace name=substr(name,1,length(name)-1)
egen address=ends(name),p(,) l
replace name=substr(name,1,length(name)-length(address))
replace name=subinstr(name,","," ",.)

报纸
jzhyue 发表于 2011-10-14 10:00:50
professionaldu 发表于 2011-10-14 03:48
谢谢
这个程序是个子程序,有一个母程序导入,由于有多个数据库,每个导入时生成的变量数不同,所以要先 ...
没有看清你的要求,还认为address后面的空变量是用"00000"表示呢.
如果用你的思路,需要你提供示例数据方能调试.
不过总觉得有些繁

地板
jzhyue 发表于 2011-10-14 10:42:21
*试一下这个,不受变量多少的限,但受变量命名法则和字符串长度的限制,好像stata12字符串长度比较的长
foreach i of varlist v*{
replace name=name+`i'+"     "
}
replace name=rtrim(name)
replace name=subinstr(name,"     ",",",.)
egen address=ends(name),p(,) l
replace name=subinstr(name,","+address,"",.)
replace address=subinstr(address,"00000","N/A",.)

7
jzhyue 发表于 2011-10-14 11:28:59
professionaldu 发表于 2011-10-14 03:48
谢谢
这个程序是个子程序,有一个母程序导入,由于有多个数据库,每个导入时生成的变量数不同,所以要先 ...
*根据你的思路(有点被你的思路搞蒙了,有点当年我学Passal传统编程语言的味道.)试试下面:
gen str40 name=""
foreach n of numlist 10/4 {
        cap confirm v v`n'
        if _rc==0{
                foreach m of numlist 3/`n'{
                        replace name=name+v`m'+","
        }
                continue, break       
        else{
        continue, break
        }
        }
}
replace name=subinstr(name,",,","",.)
replace name=substr(name,1,length(name)-1) if substr(name,-1,.)==","
egen address=ends(name),p(,) l
replace name=substr(name,1,length(name)-length(address)-1)
replace address=subinstr(address,"00000","N/A",.)

8
jzhyue 发表于 2011-10-14 11:32:57
另外,还有一种思路:用reshape也可以避免关于空值的影响.同时也可避免变量数之未知的麻烦.
这个留给楼主吧.

9
professionaldu 发表于 2011-10-18 02:01:55
jzhyue 发表于 2011-10-14 11:28
*根据你的思路(有点被你的思路搞蒙了,有点当年我学Passal传统编程语言的味道.)试试下面:
gen str40 name ...
谢谢你的回复,我现在用下面的程序在子程序里跑没问题了,但是一旦用母程序调用就会提示我invalid foreach,不知道foreach是不是在使用上有什么限制啊?

10
professionaldu 发表于 2011-10-18 02:08:34
jzhyue 发表于 2011-10-14 11:28
*根据你的思路(有点被你的思路搞蒙了,有点当年我学Passal传统编程语言的味道.)试试下面:
gen str40 name ...
具体一点,母程序是这样的:
* Read in the Creditor records for each of the boroughs;
#delimit;
do "J:\DEPT\REUP\Core Data\Lis Pendens - PDC\lp_creditor1x.do" BX;
然后在子程序里:

**************;
** Creditor **;
#delimit;

args lpboro;
insheet using "J:\DEPT\REUP\Core Data\Lis Pendens - PDC\LP_`lpboro'.txt", clear;
keep if v1=="CR";
rename v2 key;

gen str40 name=""
foreach n of numlist 10/4 {
        cap confirm v v`n'
        if _rc==0{
                        tostring v`n', replace
                foreach m of numlist 3/`n'{
                        replace name=name+v`m'+","
        }
                continue, break        
        else{
        continue, break
        }
        }
}
replace name=subinstr(name,".","",.)
replace name=subinstr(name,",,","",.)
replace name=substr(name,1,length(name)-1) if substr(name,-1,.)==","
egen address=ends(name),p(,) l
replace name=substr(name,1,length(name)-length(address)-1)
replace address=subinstr(address,"00000","N/A",.)
       
replace name = trim(name)
egen tag = tag(key name address)
        tab tag
        drop if tag==0

keep key name address

compress
sort key

save "J:\DEPT\REUP\Core Data\Lis Pendens - PDC\temp data\creditor_`lpboro'.dta", replace;

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注jltj
拉您入交流群
GMT+8, 2026-1-8 13:04