SAS Удаляет разделители между датами

#sas #delimiter

Вопрос:

Я работаю в SAS с данными биологического тестирования, которые содержат несколько возможных дат тестирования и сбора. Меня интересует удаление системы нумерации входных данных и выбор самой последней даты тестирования. Самая последняя дата тестирования всегда является первой доступной датой, но иногда эта дата отсутствует.

Например, входные данные для одной записи [1]04/04/2004[2]02/10/2002[3]2/02/2002[4]01/01/2001 и так далее. Случаи варьируются от 1 до 38 дат под одной переменной. Я заинтересован в удалении системы нумерации в [] и выборе самой последней даты тестирования. Самая последняя дата тестирования всегда является первой доступной датой.

Я пытался использовать

 var=substr(var, x,x)
 

однако это создает проблему, когда первая дата пуста.

Я надеюсь, что правильно объяснил это, пожалуйста, дайте мне знать, если потребуются какие-либо разъяснения.

Спасибо!

Комментарии:

1. Значит, значения уже находятся в символьной переменной? Или вы считываете значения из текстового файла? Пожалуйста, покажите пример, как выглядит значение, когда отсутствует первая дата.

2. Если это текстовый файл, вам следует создать резервную копию и перечитывать его по-другому. Тогда вы сможете поместить каждое поле в отдельный столбец и работать с ним немного проще.

3. @Reeza изначально это файл excel. Я не уверен, как разделить столбцы независимо от того, каким способом я ввожу файл? То, как это представлено, — это то, как оно было извлечено из исходного источника. Спасибо за вашу помощь!

4. @Tom спасибо за вашу помощь! Таким образом, значения уже находятся в символе. Пропущенные даты могут выглядеть так [1][2][3][4][5]05/30/2021[6]04/34/2020. В конце концов, значение есть, но оно находится далеко внизу списка, иногда на 10-м месте или выше. Ваш пример очень полезен, спасибо! Однако меня смущает первая функция var=. Должен ли я копировать там истинные числа? В этот набор данных включено более 2000 случаев.

5. Вас волнует, каков индекс? Вам нужно когда-нибудь знать, что это 6 — е свидание? Или 5-е свидание?

Ответ №1:

Вы должны иметь возможность использовать функцию СКАНИРОВАНИЯ() для извлечения первых строк даты. Остановитесь, когда получите действительную строку даты.

Сначала давайте превратим ваши примеры в реальный набор данных.

 data have;
  input var $80. ;
cards;
[1]04/04/2004[2]02/10/2002[3]2/02/2002[4]01/01/2001
[1][2][3][4][5]05/30/2021[6]04/34/2020
;
 

Теперь мы можем использовать SCAN() с модификатором M для сканирования строки. Вы можете использовать функцию COUNTW (), чтобы знать, когда нужно остановиться.

 data want;
  set have ;
  do index=3 by 2 to countw(var,'[]','m') until (date ne .);
    date=input(scan(var,index,'[]','m'),mmddyy10.);
  end;
  format date yymmdd10.;
run;
 

Результаты:

                         var                            index          date
[1]04/04/2004[2]02/10/2002[3]2/02/2002[4]01/01/2001       3     2004-04-04
[1][2][3][4][5]05/30/2021[6]04/34/2020                   11     2021-05-30
 

Комментарии:

1. Кто не помнит 34 апреля ? Возможно, это был день, когда я умолял 5-го.

2. День звездных войн. «Да пребудет с вами 4-е число».

Ответ №2:

Вы можете использовать шаблон регулярного выражения для поиска конструкции m/d/y в строке.

Пример:

Предполагайте только действительные даты. Если обнаружена недопустимая запись, похожая на дату, дата будет отсутствовать, и шаг ВВОДА ДАННЫХ будет зарегистрирован NOTE: Invalid argument to function INPUT ...

 data have;
  input var $80. ;
cards;
[1]04/04/2004[2]02/10/2002[3]2/02/2002[4]01/01/2001
[1][2][3][4][5]05/30/2021[6]04/34/2020
[1]12/32/2021
;

data want(label='First occuring date in var' keep=var newestdate);
  set have;

  date_rxid = prxparse ('#d{1,2}/d{1,2}/(d{2}|d{4})#'); /* presume m/d/y */

  start = 1;
  stop = -1;

  call prxnext(date_rxid, start, stop, var, position, length);

  if position then newestdate = input (substr(var,position,length), mmddyy10.);

  format newestdate date11.;
run;