首页 > 解决方案 > 将数据从长格式重组为宽格式

问题描述

您好我正在尝试使用数据步骤和数组将长格式转换为宽格式。最初我的表格是宽格式的,我想出了如何使它成为长格式,但现在我需要使用一个数组来使它再次变宽。当我运行最后一个数据步骤的代码时,我得到一个表,其中包含空的 Expense1、Expense2、Expense 3 等列。我的表需要看起来像这样,但有九个酒店和六个费用列。

采取 费用1 费用2 费用3 费用 4
1号酒店 165.89 美元 45.50 美元 $78.00 56.25 美元
酒店2 215.32 美元 $64.00 54.00 美元 62.50 美元

长桌是这样的,但有九家旅馆。

采取 费用编号 费用
1号酒店 1 165.89 美元
1号酒店 2 45.50 美元
1号酒店 3 $78.00

这是我的代码,但最后一个数据步骤是我试图将它从长转换为宽。

proc import datafile="/home/u54324957/The 
Files/Hotels.xlsx" out=Sheet1 
    dbms=xlsx replace;
data Hotels;
set Sheet1;
array TheExpense(*) Expense1-Expense6;
array Peak(6) PeakExpense1-PeakExpense6;

do i=1 to 6;
    Peak(i)=TheExpense(i) * 1.25;
    drop i;
    drop Expense1-Expense6;
    format PeakExpense1-PeakExpense6 
dollar7.2;
end;
run;
title "Peak Season Resort Pricing";

proc print data=Hotels noobs;
run;
data Hotels1;
set Sheet1;
array Hotels(*) Expense1-Expense6;
do ExpenseID=1 to 6;
Expense = Hotels(ExpenseID);
drop Expense1-Expense6;
output;
end;
run;
title "Restructure Data from Wide to Long 
Format";
proc print data=Hotels1 noobs;
format Expense dollar7.2;
run;
proc sort data=Hotels1;
by ExpenseID;
run;
data Hotels2;
set Hotels1;
array Hotels(*) Expense1-Expense6;
retain Expense1-Expense3;
by ExpenseID;
if first.ExpenseID then i=0;
i+1;
if last.ExpenseID then output;
run;
proc print data=Hotels2;
run; 

关于如何用值填充这些空列的任何想法?

标签: sas

解决方案


可以按如下方式完成基于数组的按组转置:

data wide(keep=resort expense1-expense6);

  if 0 then set tall (keep=resort); * prep PDV with resort variable;

  array expenses expenses1-expenses6; * prep PDV with wide variables;
  
  * reset array to zeroes, resorts without a specific expenseID will have a 0;
  do index = 1 to dim(expenses);
    expenses[index] = 0;
  end;

  * if you want missing values instead of zeroes;
  * call missing (of expenses(*));

  * dow loop, iterate down the by group;
  do until (last.resort);
    set tall;
    by resort;
    expenses[expenseID] = expense;
  end;

  *implicit output, one row per resort;
run;

推荐阅读