如何利用循环生成新变量?特定规则dummy变量生成技术问询
嘿,我来帮你搞定这个生成特定dummy变量的问题!根据你给出的规则和示例数据,我整理了两种常用工具(Stata和Python)的实现方法,包括高效的向量化操作和你提到的循环写法,你可以按需选择:
首先再明确下规则:当前经理的newdummy取值为1的条件是——所有入职时间(enterdate)早于他的经理,他们的离职日期(leavedate)都小于等于当前经理的入职日期(从你的示例数据来看,应该是包含等于的情况,比如经理B的入职日期3和经理A的离职日期3刚好衔接,所以dummy为1)。
Stata实现方法
方法1:高效向量化操作(推荐,数据量大时更快)
先按公司和入职日期排序,再计算每个经理之前所有经理的离职日期最大值,最后根据最大值和当前入职日期的关系生成dummy:
// 1. 按firm和enterdate排序 sort firm enterdate // 2. 计算每个firm内,当前经理之前所有经理的leavedate的累计最大值 bysort firm: gen max_prev_leave = max(leavedate[_n-1], max_prev_leave[_n-1]) if _n>1 // 3. 生成newdummy变量:第一个经理设为缺失(和你的示例一致),其他按规则赋值 gen newdummy = . if _n==1 replace newdummy = 1 if max_prev_leave <= enterdate & _n>1 replace newdummy = 0 if max_prev_leave > enterdate & _n>1
运行后就能得到和你示例完全匹配的结果。
方法2:循环实现(适合理解逻辑)
如果你一定要用循环来实现,也可以逐个检查每个经理的前置条件:
sort firm enterdate gen newdummy = . bysort firm: local total_mgr = _N bysort firm: forvalues i=1/`total_mgr' { if `i' == 1 { // 第一个经理保持缺失,可根据需求改为1 continue } // 检查当前经理之前是否存在入职更早但离职日期晚于当前入职日期的情况 count if enterdate < enterdate[`i'] & leavedate > enterdate[`i'] if r(N) == 0 { replace newdummy = 1 in `i' } else { replace newdummy = 0 in `i' } }
Python(Pandas)实现方法
方法1:向量化操作(推荐)
利用pandas的分组和累计最大值函数,快速生成目标变量:
import pandas as pd # 示例数据 df = pd.DataFrame({ 'mgr': ['A', 'B', 'C', 'D', 'E'], 'firm': ['x']*5, 'enterdate': [1,3,6,8,9], 'leavedate': [3,5,15,15,15], 'newdummy': [None,1,1,0,0] }) # 1. 按firm和enterdate排序 df = df.sort_values(['firm', 'enterdate']).reset_index(drop=True) # 2. 计算每个firm内,当前经理之前所有经理的leavedate累计最大值 df['max_prev_leave'] = df.groupby('firm')['leavedate'].transform(lambda x: x.shift().cummax()) # 3. 生成dummy变量 def calc_dummy(row): if pd.isna(row['max_prev_leave']): return None # 第一个经理设为缺失 return 1 if row['max_prev_leave'] <= row['enterdate'] else 0 df['newdummy_calc'] = df.apply(calc_dummy, axis=1)
执行后newdummy_calc列就和你给出的newdummy完全一致。
方法2:循环实现
如果需要更直观的循环逻辑,也可以逐行检查条件:
import pandas as pd df = pd.DataFrame({ 'mgr': ['A', 'B', 'C', 'D', 'E'], 'firm': ['x']*5, 'enterdate': [1,3,6,8,9], 'leavedate': [3,5,15,15,15], 'newdummy': [None,1,1,0,0] }) df = df.sort_values(['firm', 'enterdate']).reset_index(drop=True) df['newdummy_calc'] = None for idx in range(len(df)): if idx == 0: continue # 第一个经理保持缺失 curr_enter = df.loc[idx, 'enterdate'] # 获取当前经理之前所有经理的离职日期 prev_leaves = df.loc[:idx-1, 'leavedate'] # 检查是否所有离职日期都<=当前入职日期 if all(prev_leaves <= curr_enter): df.loc[idx, 'newdummy_calc'] = 1 else: df.loc[idx, 'newdummy_calc'] = 0
内容的提问来源于stack exchange,提问作者Michelle S.
相关产品推荐
相关产品推荐

