前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SAS-100种数据转置的方法,你在用哪种?

SAS-100种数据转置的方法,你在用哪种?

作者头像
Setup
发布2019-10-21 16:19:38
2.9K0
发布2019-10-21 16:19:38
举报

最近在论坛、群里面经常看到有人问数据转置相关的问题,那么今天小编就在来说一说数据集的转置,之前虽然也写过proc transpose相关的推文,那么今天我还要写...不仅仅要写这个!我还要写小编在数据转置上的成长历程...

数据转置难么?

数据集的转置难么?其实不难,在我刚学SAS的前俩周,我眼里的数据集转置是set、keep、rename,基础吧!Data步里面特别基础的知识!能数据集的转置?当然能。当时的小编做到的还是Epi的系统的项目的,接下来与小编来看一看一个实验室的检查的数据集转置!现在以及找不到当时的数据集了,就随便找了一个简化的版的数据来做实例。

将如上,小横表装置成纵表:如何用rename、keep、set来操作呢;见下代码

代码语言:javascript
复制
%macro test;
%do i=1 %to 3;
data temp&i.;
  set lbb1(keep=subjid LBBORRES&i. LBBORUOT&i. LBBCLSIG&i. LBBCOM&i.);
  LBTEST="&i.";
  rename LBBORRES&i.=LBORRES  LBBORUOT&i.=LBORUOT LBBCLSIG&i.=LBCLSIG  LBBCOM&i.=LBBCOM;
run;
%end;
data final;
  set temp1-temp3;
run;
%mend;
%test;

用的是最基础的语句的...基本上没有任何知识点啥的...转置成如下

既然横线转置成纵向,那么纵向在转置回去是不是也可以用这样的最通俗的语句实现呢?是的,见下面的代码!

代码语言:javascript
复制
%macro test;
%do i=1 %to 3;
data temp&i.;
  set final;
  where  LBTEST="&i.";
  rename LBORRES=LBBORRES&i.  LBORUOT=LBBORUOT&i. LBCLSIG= LBBCLSIG&i.  LBBCOM=LBBCOM&i.;
run;
proc sort data=temp&i.  out=temp&i.  sortseq=linguistic(numeric_collation=on);by  SUBJID;quit;
%end;
data want;
  merge temp1-temp3;
  by subjid;
run;
%mend;
%test;

我升级了

前面的代码!请轻喷!这是我接触SAS后2周做测试项目,做的实验室转置方式!

写在这里,其实也是要说,转置真的不难!最基础的语句都能“简单”(原理简单,真实的情况代码写起来会很长)

只要不嫌麻烦!这种方式基本上能实现各种转置吧!在用这种方式,写了几百行代码后,看到带我的人就用几行代码解决了问题!然后,我就开始了学习数组~数组就开始陪伴我写转置很长一段时间了...(

其实现在也不怎么用数组了,数组也被我摒弃了...很久不写已经忘的差不多了,用词不当之处,还请各位大神指正一二).接着上面的那个例子来初识数组。用数组来试下横向转置成纵向~

代码语言:javascript
复制
data want;
set lbb1;
array ar1(*)  LBBORRES1-LBBORRES3;
array ar2(*)  LBBORUOT1-LBBORUOT3;
array ar3(*)  LBBCLSIG1-LBBCLSIG3;
array ar4(*)  LBBCOM1-LBBCOM3;
do i=1 to dim(ar1);
LBTEST=i;
LBORRES=ar1(i);
LBORUOT=ar2(i);
LBCLSIG=ar3(i);
LBBCOM=ar4(i);
output;
end;
keep subjid LBORRES LBORUOT LBCLSIG LBBCOM LBTEST;
run;

可能看着和上面代码差不多!其实不管在效率还是代码的精简上还是差很多的!只是小编的这个例子举的可能不太好!那么数组是否可以纵向转置成横向呢?是可以的,接下来就来看看数组纵向转置成横向在此处的应用!

代码语言:javascript
复制
proc sort data=want  out=want  sortseq=linguistic(numeric_collation=on);by subjid  LBTEST;quit;
data want1;
set want;
by subjid  LBTEST;
retain  LBBORRES1-LBBORRES3 LBBORUOT1-LBBORUOT3 LBBCLSIG1-LBBCLSIG3 LBBCOM1-LBBCOM3 i ;
array ar1(*)   LBBORRES1-LBBORRES3;
array ar2(*)  LBBORUOT1-LBBORUOT3;
array ar3(*)  LBBCLSIG1-LBBCLSIG3;
array ar4(*)  LBBCOM1-LBBCOM3;
if first.subjid then  i=1;
else i+1;
ar1(i)=LBORRES;
ar2(i)=LBORUOT;
ar3(i)=LBCLSIG;
ar4(i)=LBBCOM;
if last.subjid then output;
keep subjid LBBORRES: LBBORUOT: LBBCLSIG: LBBCOM: ;
run;

看起来是有些繁琐一些!是的,数组横向转置纵向的思维比较好理解,纵向转置成横向感觉理解起来不是那么方便自如!可能还是小编使用的不够熟练,所以才有这样的感觉!

进入主题array

开始进入本文的主要部分了,其实也是打算对数组进行一个简单的介绍,当然介绍的一维数组,多维数组以目前我的工作还没有接触到,所以我也没进行研究过,因此我这次也就不说了。当然数组的作用不局限于数据的转置,但小编数组使用最多的还是在数据转置的场景下,所以呀,例子也仅举转置。

首先,数组是什么,可以理解成在内存中开辟了一个空间,然后给这个空间安上凳子,将你需要放入这空间的东西(变量,字符串,数字等)对号入组,最后通过调用这个空间的名字(数组的名字),以及凳子号(数组的下脚标)来提取数据。小编是这样浅显的理解的...

如何定义数组?网上找了一个图,感觉还挺好的,见下图!

这里需要注意的是,定义数组的时候,数值型与字符型不能混合的一起。说到这儿,如果上面那段代码不keep seq name;数据集会是什么样的呢?

为啥数据集有这么多变量呢?而且数组变量名是不是很眼熟?数组的名称+数组的脚标,数组其实就类似一个大横表..那么这样创建数组是不是会影响运行的效率呢?当数据量大的时候,是特别的影响运行的效率的。有什么办法解决这个问题呢?可以创建数组的时候的声明一下数组是一个临时数组,这样数组的值就不会出现在数据集里面了,会提高一下运行的效率..接下来看下图。

虽然临时数组会提高运行效率,但是也有缺陷,需要慎用。一般我都不用的。这里的例子都是塞入固定的数值、字符串。当然还是可以塞入变量的,就如同最开始的转置的例子,就是往数组塞入变量。在就不在多举例子了,好像一维数组在就没有别的啥要注意的,奥,还有数组脚标不要越界了...不然就会出ERROR的~见下图

我又升级了

我用数组转置,我大概用了一年了,虽然一直知道transpose可以转置,当时由于种种原因没有对transpose好好了解一下,后来突然想换方式转置了,就对proc transpose做了一些学习,然后就不可自拔了

现在转置一般都用transpose了,因为效率确实比数组高,尤其针对大数据处理的时候!关于proc transpose结构我这里就不在说了,以前的推送多次有用到与专门写过了,可点击此处SAS Proc transpose过程步,当然也可以点击SAS-一条群消息引发的思考,当然还可以在此点击SAS- 100种数据compare的方式,你在用哪种?,里面都有transpose使用的实例。当然也可以不点击~因为下面,马上要有很多例子了~

我回答过的几个简单转置

例一:是一个简单的转置~

代码语言:javascript
复制
data have;
input Dependent $ obs  orres;
cards;
AL_Mean  1 -41.4706
AL_Mean  2 10.7621
cr2_Mean 1 -1.2781
cr2_Mean 2 0.2003
Mn_Mean  1 -13.7115
Mn_Mean  2 4.0014
;
run;
proc sort data=have  out=have ;by  obs;;quit;
proc transpose data=have out=want(drop=_:);
by  obs;
var  orres;
id Dependent ;
run;

嗯!上面是利用proc transpose实现的过程,那么接下来在来看看array如何实现...

代码语言:javascript
复制
proc sql noprint;
    select distinct Dependent into:varlist1 separated by " " from have order by  Dependent  ;
quit;
%put NOTE:&varlist1.;
proc sort data=have  out=want  sortseq=linguistic(numeric_collation=on);by obs Dependent  ;quit;
data want1;
set want;
by obs Dependent  ;
retain  &varlist1. i ;
array ar1(*)  &varlist1.;
if first.obs then  i=1;
else i+1;
ar1(i)=orres;
if last.obs then output;
keep obs &varlist1.;
run;

说实话,这里用数组纵转横我还真不太擅长和习惯...接下来在看一个例子

这转置其实也是很简单的,不过得多操作几步!接下来看代码如何来试下~

代码语言:javascript
复制
data test;
input person $ city $ Age $ product $  Brand $;
cards;
A SH 22 P1 APPLE
A SH 22 P2 VIVO
B BJ 35 P3 HUAWEI
B BJ 35 P4 SAMSUNG
B BJ 35 P5 SAMSUN
C GZ 50 P5 MI
;
run;
proc sort data=test  out=test ;by  person city  Age ;;quit;
data test;
  set test ;
  by  person city  Age ;
  if first.person then x=1;
  else x+1;
  array aa[*] product brand;
  do i=1 to dim(aa);
  _Name_=strip(vname(aa[i]))||strip(vvalue(x));
  Value=aa[i];
  output ;
  end;
  keep person city  Age _Name_ Value;
run;
proc transpose data=test out=test1(drop=_:);
   by person city age;
   var value;
run;

当然上面的代码不段用到数组,也用到了proc transpose。当然仅仅用transpose也是能实现的,只不过要多转几次!代码就不在这里贴了。

今天就这么多了,后续内容,敬请期待~

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-03-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SAS程序分享号号号 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数据转置难么?
  • 我升级了
  • 进入主题array
  • 我又升级了
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档