Решение SPSS AnswerNet Код решения: 100000483 Продукт: SPSS Base Версия: ОС: Тип вопроса: Синтаксис/Скрипты/Пакетный режим Подтип вопроса: Дата и время Заголовок: Генерация случайных дат из заданного интервала Описание: Вопрос. Как мне сгенерировать 100 случайных дат между 1 января 1920 года и 31 декабря 1989, включительно? Ответ. Ниже представлены 2 варианта синтаксиса. Первый осуществляет случайную выборку дат с возвращением, т.е. некоторая дата может быть отобрана более одного раза. Второй вариант делает выборку без возвращения. После этих двух примеров приводятся несколько команд, с помощью которых вы можете получить представление о распределении дат, полученных в результате. Вариант 1: даты отбираются с возвращением: Даты хранятся в SPSS как число секунд, прошедших с начала отсчёта григорианского календаря, т.е. с полуночи 14 октября 1582 года. Для создания каждой случайной даты программа генерирует случайное число секунд из интервала, соответствующего нужному интервалу дат, и сохраняет его в переменной RDAY. Функция XDATE.DATE "отсекает" часть дня таким образом, что переменная RDAY содержит число секунд, прошедших до полуночи (до начала) данного дня. После этого с помощью формата даты настраивается нужное отображение содержимого RDAY (в данном случае используем формат ADATE10). Обратите внимание, в качестве конечной даты интервала был выбран следующий день после 31.12.1989. Это потому, что функция генерации случайных чисел rv.uniform(a,b) генерирует числа между a и b, не включая края интервала. Таким образом, указав конечную дату 01.01.1990, мы гарантируем, что максимальным числом, сгенерированным функцией rv.uniform, будет число, соответствующее 11:59:59 31 декабря 1989 года. Для начальной даты указывать предыдущий день не требуется. Хотя число, в точности соответствующее полуночи 1 января 1920 года не может быть сгенерировано, любое число, начиная со следующей за полуночью секундой и до последней секунды этого дня, будет отнесено к 1 января 1920 году. *генерируем 100 случайных дат между 1.1.1920 и 31.12.1989 (включительно). *с возвращением. new file. input program. loop #i = 1 to 100. compute rday = xdate.date(rv.uniform(date.dmy(1,1,1920),date.dmy(1,1,1990))). end case. end loop. end file. end input program. execute. formats rday (adate10). Вариант 2. даты отбираются без возвращения: Для выбора без возвращения мы сначала составляем полный список дат из заданного интервала так, чтобы каждая дата повторялась в нём лишь один раз. В переменную RDAY мы помещаем числа, начиная с числа дней, прошедших с начала отсчёта григорианского календаря к 1.1.1920, и заканчиваем числом дней, прошедших с той же точки отсчёта к 31.12.1989. Каждое новое наблюдение, таким образом, представляет собой очередную дату. Использование функции YRMODA освобождает нас от необходимости высчитывать начало и конец цикла LOOP вручную. Затем мы генерируем случайную переменную и добавляем её к файлу данных. После этого мы ранжируем наблюдения по значениям этой случайной переменной. Ранги сохраняются в переменной RX. Значения рангов - не что иное, как случайный порядок дней в нужном нам интервале. Отбирая наблюдения, ранги которых RX<=100, мы получаем выборку 100 случайных дней без возвращения из нужного интервала. Теперь нужно умножить значения RDAY на 86400 (число секунд в сутках) и применить форматирование для переменной даты. В отличие от первого варианта, масштаб случайной переменной, генерируемой с помощью rv.uniform во втором варианте, не важен. Первая и последняя дата временного интервала были включены в исходный файл данных. Здесь не нужно указывать верхнюю границу как 1 января 1990 года, чтобы на самом деле получить 31 декабря 1989-го. * генерируем 100 случайных дат между 1.1.1920 и 31.12.1989 (включительно). * без возвращения. new file. input program. loop rday = yrmoda(1920,1,1) to yrmoda(1989,12,31). compute x = rv.uniform(0,1). end case. end loop. end file. end input program. execute. rank variables = x /rank into rx. select if (rx <= 100). execute. compute rday = rday*86400 . formats rday (adate10). execute. * после получения файла переменные x и rx можно удалить. * Для обоих вариантов визуально проверить результаты генерации можно, * построив распределения полученных дат. * (для этого предварительно объединим их в декады). compute decade = trunc(xdate.year(rday)/10)*10. formats decade (f8). frequencies decade. Создано: 25.8.1999.