Sql 根据取决于组变量和年份序列的条件在SAS中删除观测值

Sql 根据取决于组变量和年份序列的条件在SAS中删除观测值,sql,sas,Sql,Sas,从一个包含变量id的SAS数据集(该变量识别人和year由2000-2010年组成)中,我想通过删除那些在原始数据集中至少连续三年未被观察到的个体来创建一个新的数据集 以下是原始数据集的外观: id year 1 2002 1 2003 1 2004 1 2005 1 2006 2 2000 2 2002 2 2003 2 2005 2 2007 2 2009 2 2010 3 2000 3 2002 3 2003 3 2004 3 2007 3 2009

从一个包含变量
id
SAS数据集(该变量识别人和
year
由2000-2010年组成)中,我想通过删除那些在原始数据集中至少连续三年未被观察到的个体来创建一个新的数据集

以下是原始数据集的外观:

id year 
1  2002
1  2003
1  2004
1  2005
1  2006
2  2000
2  2002
2  2003
2  2005
2  2007
2  2009
2  2010
3  2000
3  2002
3  2003
3  2004
3  2007
3  2009
3  2010
一个人不一定在11年中的每一年都被观察到。就上述数据集而言,我想删除
id=2
的观察值

以下说明如何确定哪些
id
连续三年有记录:

PROC SQL;
  SELECT DISTINCT t1.ID
  FROM MyTable t1
  INNER JOIN MyTable t2 ON t1.id = t2.id AND t1.year = t2.year + 1 
  INNER JOIN MyTable t3 ON t2.id = t3.id AND t2.year = t3.year + 1;
QUIT;
要获取所有数据,请使用:

下面显示了如何确定哪些
id
具有连续三年的记录:

PROC SQL;
  SELECT DISTINCT t1.ID
  FROM MyTable t1
  INNER JOIN MyTable t2 ON t1.id = t2.id AND t1.year = t2.year + 1 
  INNER JOIN MyTable t3 ON t2.id = t3.id AND t2.year = t3.year + 1;
QUIT;
要获取所有数据,请使用:

下面显示了如何确定哪些
id
具有连续三年的记录:

PROC SQL;
  SELECT DISTINCT t1.ID
  FROM MyTable t1
  INNER JOIN MyTable t2 ON t1.id = t2.id AND t1.year = t2.year + 1 
  INNER JOIN MyTable t3 ON t2.id = t3.id AND t2.year = t3.year + 1;
QUIT;
要获取所有数据,请使用:

下面显示了如何确定哪些
id
具有连续三年的记录:

PROC SQL;
  SELECT DISTINCT t1.ID
  FROM MyTable t1
  INNER JOIN MyTable t2 ON t1.id = t2.id AND t1.year = t2.year + 1 
  INNER JOIN MyTable t3 ON t2.id = t3.id AND t2.year = t3.year + 1;
QUIT;
要获取所有数据,请使用:


SQL当然可以做到这一点,但SAS可以更轻松地做到这一点(无需连接)。这假设它是按id和年份提前排序的,如您的示例所示,否则您需要排序。
这基本上是一个一次性解决方案(在这里,它只读取一次数据,除非一个ID的记录多于要保存的缓冲内存,但在本例中不太可能)

这是double DoW循环的一个示例,该循环首先检查一个ID组中的行的条件,然后第二次遍历它们以输出符合条件的ID行

data have;
 input id year;
 datalines;
1  2002
1  2003
1  2004
1  2005
1  2006
2  2000
2  2002
2  2003
2  2005
2  2007
2  2009
2  2010
3  2000
3  2002
3  2003
3  2004
3  2007
3  2009
3  2010
;;;;
run;

data want;
 do _n_=1 by 1 until (last.id);
  set have;
  by id;
  yrdif=dif(year);
  if yrdif=1 then cons_yr=cons_yr+1;
  else cons_yr=1;
  max_cons = max(cons_yr,max_cons);
 end;
 do _n_=1 by 1 until (last.id);
  set have;
  by id;
  if max_cons ge 3 then output;
 end;
run;

SQL当然可以做到这一点,但SAS可以更轻松地做到这一点(无需连接)。这假设它是按id和年份提前排序的,如您的示例所示,否则您需要排序。
这基本上是一个一次性解决方案(在这里,它只读取一次数据,除非一个ID的记录多于要保存的缓冲内存,但在本例中不太可能)

这是double DoW循环的一个示例,该循环首先检查一个ID组中的行的条件,然后第二次遍历它们以输出符合条件的ID行

data have;
 input id year;
 datalines;
1  2002
1  2003
1  2004
1  2005
1  2006
2  2000
2  2002
2  2003
2  2005
2  2007
2  2009
2  2010
3  2000
3  2002
3  2003
3  2004
3  2007
3  2009
3  2010
;;;;
run;

data want;
 do _n_=1 by 1 until (last.id);
  set have;
  by id;
  yrdif=dif(year);
  if yrdif=1 then cons_yr=cons_yr+1;
  else cons_yr=1;
  max_cons = max(cons_yr,max_cons);
 end;
 do _n_=1 by 1 until (last.id);
  set have;
  by id;
  if max_cons ge 3 then output;
 end;
run;

SQL当然可以做到这一点,但SAS可以更轻松地做到这一点(无需连接)。这假设它是按id和年份提前排序的,如您的示例所示,否则您需要排序。
这基本上是一个一次性解决方案(在这里,它只读取一次数据,除非一个ID的记录多于要保存的缓冲内存,但在本例中不太可能)

这是double DoW循环的一个示例,该循环首先检查一个ID组中的行的条件,然后第二次遍历它们以输出符合条件的ID行

data have;
 input id year;
 datalines;
1  2002
1  2003
1  2004
1  2005
1  2006
2  2000
2  2002
2  2003
2  2005
2  2007
2  2009
2  2010
3  2000
3  2002
3  2003
3  2004
3  2007
3  2009
3  2010
;;;;
run;

data want;
 do _n_=1 by 1 until (last.id);
  set have;
  by id;
  yrdif=dif(year);
  if yrdif=1 then cons_yr=cons_yr+1;
  else cons_yr=1;
  max_cons = max(cons_yr,max_cons);
 end;
 do _n_=1 by 1 until (last.id);
  set have;
  by id;
  if max_cons ge 3 then output;
 end;
run;

SQL当然可以做到这一点,但SAS可以更轻松地做到这一点(无需连接)。这假设它是按id和年份提前排序的,如您的示例所示,否则您需要排序。
这基本上是一个一次性解决方案(在这里,它只读取一次数据,除非一个ID的记录多于要保存的缓冲内存,但在本例中不太可能)

这是double DoW循环的一个示例,该循环首先检查一个ID组中的行的条件,然后第二次遍历它们以输出符合条件的ID行

data have;
 input id year;
 datalines;
1  2002
1  2003
1  2004
1  2005
1  2006
2  2000
2  2002
2  2003
2  2005
2  2007
2  2009
2  2010
3  2000
3  2002
3  2003
3  2004
3  2007
3  2009
3  2010
;;;;
run;

data want;
 do _n_=1 by 1 until (last.id);
  set have;
  by id;
  yrdif=dif(year);
  if yrdif=1 then cons_yr=cons_yr+1;
  else cons_yr=1;
  max_cons = max(cons_yr,max_cons);
 end;
 do _n_=1 by 1 until (last.id);
  set have;
  by id;
  if max_cons ge 3 then output;
 end;
run;


你为什么要放弃身份证2。它已经连续四年(2002年、2003年、2004年和2005年)?我在编写示例数据时犯了一个错误。我会纠正的。谢谢你为什么要放弃身份证2。它已经连续四年(2002年、2003年、2004年和2005年)?我在编写示例数据时犯了一个错误。我会纠正的。谢谢你为什么要放弃身份证2。它已经连续四年(2002年、2003年、2004年和2005年)?我在编写示例数据时犯了一个错误。我会纠正的。谢谢你为什么要放弃身份证2。它已经连续四年(2002年、2003年、2004年和2005年)?我在编写示例数据时犯了一个错误。我会纠正的。ThanksMy数据集是SAS格式的,我想在SAS中执行此操作。在使用自己的数据集更改MyTable之后,是否应该在SAS中运行您的代码?我对SASI完全陌生,我对SAS不熟悉。我只能说试试看。它不应该伤害任何东西,因为它只是一个简单的SELECT语句;退出。是,将MyTable更改为数据集的名称。另外,如果您不知道如何使用SQL解决方案,请不要在问题中添加标签…我的数据集是SAS格式的,我希望在SAS中执行此操作。在使用自己的数据集更改MyTable之后,是否应该在SAS中运行您的代码?我对SASI完全陌生,我对SAS不熟悉。我只能说试试看。它不应该伤害任何东西,因为它只是一个简单的SELECT语句;退出。是,将MyTable更改为数据集的名称。另外,如果您不知道如何使用SQL解决方案,请不要在问题中添加标签…我的数据集是SAS格式的,我希望在SAS中执行此操作。在使用自己的数据集更改MyTable之后,是否应该在SAS中运行您的代码?我对SASI完全陌生,我对SAS不熟悉。我只能说试试看。它不应该伤害任何东西,因为它只是一个简单的SELECT语句;退出。是,将MyTable更改为数据集的名称。另外,如果您不知道如何使用SQL解决方案,请不要在问题中添加标签…我的数据集是SAS格式的,我希望在SAS中执行此操作。在使用自己的数据集更改MyTable之后,是否应该在SAS中运行您的代码?我对SASI完全陌生,我对SAS不熟悉。我只能说试试看。它不应该伤害任何东西,因为它只是一个简单的SELECT语句;退出。是的,c