Длина строки таблицы SAS (предел) - PullRequest
3 голосов
/ 16 декабря 2010

Я создаю таблицу SAS, в которой одно из полей должно содержать огромную строку.

Ниже приведена моя таблица (TABLE name = MKPLOGS4):

OBS    RNID        DESCTEXT
       ---------   -----------
1       123         This is some text which is part of the record. I want this to appear
2       123         concatenated kinda like concat_group() from MYSQL but for some reason
3       123         SAS does not have such functionality. Now I am having trouble with
4       123         String concatenation.
5       124         Hi there old friend of mine, hope you are enjoying the weather
6       124         Are you sure this is not your jacket, okay then. Will give charity.
.       .           .
.       .           .
.       .           .

и мне нужно получить таблицу, подобную этой (имя таблицы = MKPLOGSA):

OBS    RNID        DESCTEXT
       ---------   -----------
1       123         This is some text which is part of the record. I want this to appear concatenated kinda like concat_group() from MYSQL but for some reason SAS does not have such functionality. Now I am having trouble with String concatenation.
2       124         Hi, there old friend of mine, hope you are enjoying the weather Are you sure this is not your jacket, okay then. Will give charity.
.       .           .
.       .           .
.       .           .

Итак, после неудачной попытки с SQL, я придумал следующий код SAS (обратите внимание, я очень новичок в SAS):

DATA MKPLOGSA (DROP = DTEMP DTEXT);
  SET MKPLOGS4;
  BY RNID;

  RETAIN DTEXT;

  IF FIRST.RNID THEN
  DO;
  DTEXT = DESCTEXT;
  DELETE;
  END;
  ELSE IF LAST.RNID THEN
  DO;
    DTEMP = CATX(' ',DTEXT,DESCTEXT);
    DESCTEXT = DTEMP;
  END;
  ELSE
  DO;
    DTEMP = CATX(' ',DTEXT,DESCTEXT);
    DTEXT = DTEMP;

  DELETE;
  END;

Журнал SAS выдает это предупреждение:

WARNING: IN A CALL TO THE CATX FUNCTION, THE BUFFER ALLOCATED 
FOR THE RESULT WAS NOT LONG ENOUGH TO CONTAIN THE CONCATENATION 
OF ALL THE ARGUMENTS. THE CORRECT RESULT WOULD CONTAIN 229 CHARACTERS, 
BUT THE ACTUAL RESULT MAY EITHER BE TRUNCATED TO 200 CHARACTER(S) OR 
BE COMPLETELY BLANK, DEPENDING ON THE CALLING ENVIRONMENT. THE 
FOLLOWING NOTE INDICATES THE LEFT-MOST ARGUMENT THAT CAUSED TRUNCATION.

Далее следует сообщение (для шага данных SAS, который я разместил здесь):

NOTE: ARGUMENT 3 TO FUNCTION CATX AT LINE 100 COLUMN 15 IS INVALID.

Обратите внимание, что в моей таблице данных примера (MKPLOGS4) каждая строка строки для поля DESCTEXT может содержать до 116 символов, и нет ограничений на количество строк описания text / recordID.

Вывод, который я получаю, имеет только последнюю строку описания:

OBS   RNID   DESCTEXT
      ----   --------
1     123    String concatenation.
2     124    Are you sure this is not your jacket, okay then. Will give charity.
.     .      .
.     .      .
.     .      .

У меня есть следующие вопросы:

. что-то не так с моим кодом? , есть ли ограничения на конкатенацию строк SAS? Могу ли я переопределить это? Если да, укажите код.

Если у вас есть предложение, я был бы очень признателен, если бы вы опубликовали свою версию кода. Это не школьная работа / домашнее задание.

Ответы [ 3 ]

3 голосов
/ 16 декабря 2010

Поскольку SAS хранит символьные данные в виде пустых строк фиксированной длины , обычно не рекомендуется хранить большое количество текста в наборе данных. Однако, если необходимо, вы можете создать переменную символьного типа длиной до 32767 символов. Если вы не против сделать дополнительный ввод-вывод, вот простой способ.

   /* test data -- same id repeated over multiple observations i.e., in a "long-format" */
   data one;
     input rnid desctext & :$200.;
   cards;
   123 This is some text which is part of the record. I want this to appear
   123 concatenated kinda like concat_group() from MYSQL but for some reason
   123 SAS does not have such functionality. Now I am having trouble with
   123 String concatenation.
   124 Hi there old friend of mine, hope you are enjoying the weather
   124 Are you sure this is not your jacket, okay then. Will give charity.
   ;
   run;
   /* re-shape from the long to the wide-format. assumes that data are sorted by rnid. */
   proc transpose data=one out=two;
     by rnid;
     var desctext;
   run;
   /* concatenate col1, col2, ... vars into single desctext */
   data two;
     length rnid 8 desctext $1000;
     keep rnid desctext;
     set two;
     desctext = catx(' ', of col:);
   run;
2 голосов
/ 16 декабря 2010

В документации для функции catx указано, что она (по умолчанию) будет возвращать только 200 символов, если вы уже не указали длину строки, в которой сохраняете результат.

Все, что вам нужно сделать, этогде-нибудь в вашем шаге данных добавьте оператор length или attrib.

Вот как я бы его кодировал (не проверено):

data mkplogsa (rename=dtext=desctext);

  length dtext $32767 ;

  set mkplogs4;
  by rnid;

  retain dtext;

  if first.rnid then do;
    dtext = "";
  end;

  dtext = catx(' ',dtext,desctext);

  if last.rnid then do;    
    output;
  end;

  keep dtext;

run;

Обратите внимание, что 32767 - это самый большой размер строкизначение символа в наборе данных SAS.Если ваша строка больше этой, вам не повезло.

Cheers Rob

1 голос
/ 20 декабря 2010

Спасибо, ребята, я смог решить эту проблему с помощью PROC TRANSPOSE, а затем с помощью объединения. Вот код:

/*
  THIS TRANSPOSE STEP TAKES THE MKPLOGS4 TABLE AND
  CREATES A NEW TEMPORARY TABLE CALLED MKPLOGSA. SINCE
  THE DESCRIPTION TEXT IS STORED IN MULTIPLE LINES (OBSERVATIONS)
  IN THE ITEXT FILE, IN ORDER TO COMBINE THEM TO A SINGLE ROW,
  WE USE TRANSPOSE. HOWEVER, AFTER THIS STEP, THE DESCRIPTION TEXT
  SPREAD OVER MULTIPLE LINES ALTHOUGH ON SAME ROW (OBSERVATION)
  ARE STILL SEPARATED INTO MULTIPLE COLUMNS (ON THE SAME ROW)
  ALL PREFIXED IN THIS CASE BY 'DESCTEXT'. WE DROP THE AUTO-CREATED
  COLUMN _NAME_
*/
PROC TRANSPOSE DATA = MKPLOGS4 OUT = MKPLOGSA (DROP = _NAME_)
    PREFIX = DESCTEXT;
    VAR DESCTEXT;
    BY PLOG;
RUN;

/*
  THIS DATA STEP CREATES A NEW TABLE CALLED MKPLOGSB WHICH
  TAKES ALL THE SEPARATED DESCRIPTION TEXT COLUMNS AND
  CONCATENATES THEM INTO A SINGLE COLUMN - LONG_DESCRIPTION.
*/
DATA MKPLOGSB (DROP = DESCTEXT:);
    SET MKPLOGSA;
    /* CONCATENATED DESC. TEXT SET TO MAX. 27000 CHARS. */
    LENGTH LONG_DESCRIPTION $27000;

    LONG_DESCRIPTION = CATX(' ',OF DESCTEXT:);
RUN;
...