![]() |
|
SPSS присвоение значения одного наблюдения - другому - netdim
(2008/11/13 17:56)
Добрый день, помогите разрешить следующий вопрос: каким образом в SPSS можно присвоить конкретному наблюдению значение другого конкретного наблюдения?Например, имеем две переменные a и b: a | b 1 | 56 1 | 56 2 | 33 4 | 11 4 | 11 4 | 11 5 | 80 6 | 70 А мне нужно получить переменную c: a | b | c ......(в скобках приводится расшифровка как получается c) 1 | 56 | 0 .....(т.к. a=0 нет, то c=0) 1 | 56 | 0 .....(т.к. a=0 нет, то c=0) 2 | 33 | 56 ....(т.к. при a=1 b=56, то c=56) 4 | 11 | 0 .....(т.к. a=3 нет, то c=0) 4 | 11 | 0 .....(т.к. a=3 нет, то c=0) 4 | 11 | 0 .....(т.к. a=3 нет, то c=0) 5 | 80 | 11 ....(т.к. при a=4 b=11, то c=11) 6 | 70 | 80 ....(т.к. при a=5 b=80, то c=80) Т.е. смысл сводится к тому, чтобы для каждого поколения (a) проставить значения из предыдущего поколения (a-1). Значения внутри каждого поколения (a) - одинаковы (получены для каждого наблюдения путем агрегирования данных по поколениям). Поколения могут отсутствовать (в примере нет 3-го поколения), тогда значение для с(при a=4) будет либо 0, либо missing - не принципиально. Заранее прошу прощения за вопрос, он может показаться как минимум странным, но другого решения я просто не вижу. Спасибо всем кто откликнется.
Re1: SPSS присвоение значения ... - Асхат
(2008/11/13 19:30)
Сдвиньте данные на 1 наблюдение и не мучайтесь.CREATE /A_1=LAG(A 1). Создает новую переменную А_1, значения которой сдвинуты в базе вниз на одно наблюдение. То же самое для переменной В. И спокойно используем А_1 и В_1 для определения переменной С с помощью оператора IF. PS Может, начнете читать Syntax Guide когда-нибудь?
Re: Re1: SPSS присвоение значения ... - netdim
(2008/11/14 9:32)
Уважаемый Асхат! Большое спасибо что вы уделяете мне свое время ! Я правда стараюсь разбираться самостоятельно. О предложенном Вами способе я знаю, и пробовал применить к моим условиям, но не получилось, вот почему:1) Поколения может и не быть (в моем примере это 3-е поколение). В этом случае четвертому поколению присвоятся значения не 0, а значения 2-го поколения. 2) Кол-во поколений (переменная а) различное (т.е. может быть всего одно наблюдение, а может быть и 100). В этом случае правильное значение будет только у первого наблюдения в каждом поколении (у всех остальных они будут неверные). Здесь одним сдвигом не обойтись, т.к. некоторые значения нужно будет сдвинуть на 1 наблюдение, а некоторые на 100 наблюдений. Здесь бы подошел следующий способ (как реализовать его в СПСС я не знаю пока): - для всех поколений подставлять любое значение из предыдущего поколения (любое, т.к. значения эти одинаковые (агрегированные по поколениям)). Можно, кстати, агрегировать данные в новый файл, но здесь опять возникает проблема отсутствия некоторых поколений как таковых...
Re2: SPSS присвоение значения ... - Асхат
(2008/11/14 11:14)
Ладно, понял, извините за наезд ;-)Итак, пробуем усложнить задачу. Я исхожу из того, что исходный файл отсортирован по переменной A. Если нет, надо добавить сортировку и сохранить. Первое - создаем таки новую переменную. compute A1=A-1. exe. Получим нечто вроде A B A1 1 56 0 2 33 1 4 11 3 Второе - агрегируем данные по переменной A. Aggregate outfile=key.sav /break=A /С = mean (B). Получим нечто вроде A B 1 56 2 33 4 11 теперь вызываем агрегированный файл key.sav и переименовываем переменную A Get file=key.sav. Exe. RENAME variables (A=A1). И, наконец, объединяем эти два файла по переменной-ключу A1, используя агрегированный файл как таблицу: Get file (ваш исходный файл). exe. Match files file=* /table = key.sav /by A1. Что у нас происходит. Допустим, в исходном файле А=1, тогда А1=0 В файле-таблице такого значения нет, С=sysmis (системное пропущенное). А=2, тогда А1=1 тогда по ключу в эту строчку добавляется С=56. Ну и так далее ... А B А1 С 1 56 0 . 2 33 1 56 4 11 3 . Осталось только командой recode заменить пропущенные значения в переменной С на нули и дело в шляпе. Примечание1: я этот алгоритм на практике не проверял, чисто теоретическая игра ума. Но идея, надеюсь, понятна. Если что получится - напишите о результатах. Примечание 2: в команде aggregate files вроде логичнее использовать /С = first (B), но использование среднего является дополнительной проверкой, что каждому поколению присвоено одно и то же значение переменной В. PS И все-таки не могу до сих пор понять, зачем это нужно??? :-))))
Праздничная задачка для настоящего социолога - zap
(2008/11/14 15:05)
2 Shef Ленин бы не справился ;)
Асхат! Огромное Вам спасибо! - netdim
(2008/11/17 12:58)
Идея очень даже понятна! Все реализовал, проверка, правда, немного больше времени займет, но думаю все правильно! Для чего это нужно: все банально и просто :). RollRate - анализ движения (ну например, просрочки выданных кредитов по поколениям). В итоге код следующий получился: /* RollRate!!! STRING R1(A10). COMPUTE R1 = CONCAT(STRING(Разбивка_просрочка,F5.0),STRING(Дата_код,F5.0)). SORT CASES BY R1. AGGREGATE /OUTFILE=* MODE=ADDVARIABLES /PRESORTED /BREAK=Разбивка_просрочка Дата_код /RollRate_кол_all=N. COMPUTE R2=Разбивка_просрочка - 1. COMPUTE R3=Дата_код - 1. STRING R4(A10). COMPUTE R4 = CONCAT(STRING(R2,F5.0),STRING(R3,F5.0)). EXECUTE. AGGREGATE /OUTFILE="C:\key.sav" /PRESORTED /BREAK=R1 /RollRate_кол_all_past=MEAN(RollRate_кол_all). GET FILE="C:\key.sav". RENAME VARIABLES (R1=R4). SAVE OUTFILE="C:\key.sav". EXECUTE. /* ВТОРАЯ ПОЛОВИНА MATCH FILES /FILE=* /TABLE="C:\key.sav" /BY R4. EXECUTE. ERASE FILE "C:\key.sav". У меня, правда, маленький вопросик есть еще (сейчас разбираюсь). Если этот код запустить сразу весь, данные в исходный файл не подтянуться. Если сначала выполнить первую половинку, а потом вторую, то все ОК.
На: Огромное спасибо - пожалуйста - Асхат
(2008/11/17 19:16)
Перед второй частью командой get file исходный файл надо открыть (лично мне так кажется).
Re: На: создается копия рабочего файла - netdim
(2008/11/19 11:59)
С помощью get file повторно открывается исходный файл (а он у меня уже открыт, мне необходимо в открытый исходный рабочий файл перенести столбец).
Re2: создается копия рабочего файла - Асхат
(2008/11/19 17:06)
Судя по синтаксису, после первой половины кода открытым остается не исходный файл, а key.sav - аггрегированный.
Re: Re2: создается копия рабочего файла - netdim
(2008/11/20 11:03)
Извините за такое "сумбурное" описание. Постараюсь описать более подробно: выше приведенный код выполняется без закрытия основного рабочего файла. Т.е. получается, что у меня открыт рабочий файл, затем я агрегирую данные в новый файл key.sav (открывается файл key.sav, а рабочий файл остается открытым и активным(зеленый плюсик)), затем мне нужно запустить вторую половинку (если запускать сразу весь код, что-то не срабатывает и новая переменная не переносится в рабочий файл). Получается если я воспользуюсь GET FILE, то мне откроется копия уже открытого рабочего файла, а мне нужно добавлять в оригинал. Как будет правильнее сделать: когда у меня откроется файл key.sav сразу же закрыть рабочий файл, а потом уже его опять открывать и добавлять переменную, либо есть другой способ? Спасибо.
Re: Re: Re2: создается копия рабочего файла - KO
(2008/11/20 11:55)
что-то не срабатывает и новая переменная не переносится в рабочий файл Потому что GET делает активным открываемый файл key.sav вместо вашего основного файла. Зеленый плюсик не говорит об активности массива данных для синтаксиса, а говорит о его активности для диалоговых окон меню. Когда же вы нажимаете мышкой на зеленый крестик, т.е. поднимаете свой файл перед глазами, вы делаете его активным и в том, и в другом отношении. Почитайте http://subscribe.ru/archive/comp.soft.others.spss/200708/09070610.html Вам совсем не обязательно сохранять и открывать key.sav. Воспользуйтесь работой с несколькими массивами одновременно, описываемой там. У вас лишние EXECUTE. Только самая последняя необходима.
Re: Re: Re2: создается копия рабочего файла - KO
(2008/11/20 12:42)
Короче, попробуйте вроде этого (я не проверял). Пусть ваш основной массив (dataset, не "файл") называется main_set. Вместо key.sav будет фигурировать массив key_set.STRING R1(A10). COMPUTE R1 = CONCAT(STRING(Разбивка_просрочка,F5.0),STRING(Дата_код,F5.0)). SORT CASES BY R1. AGGREGATE /OUTFILE=* MODE=ADDVARIABLES /PRESORTED /BREAK=Разбивка_просрочка Дата_код /RollRate_кол_all=N. COMPUTE R2=Разбивка_просрочка - 1. COMPUTE R3=Дата_код - 1. STRING R4(A10). COMPUTE R4 = CONCAT(STRING(R2,F5.0),STRING(R3,F5.0)). DATASET DECLARE key_set. AGGREGATE /OUTFILE=key_set /PRESORTED /BREAK=R1 /RollRate_кол_all_past=MEAN(RollRate_кол_all). DATASET ACTIVATE key_set. RENAME VARIABLES (R1=R4). MATCH FILES /FILE=main_set /TABLE=* /BY R4. EXECUTE.
Re: Re: Re: Re2: создается копия рабочего файла - KO
(2008/11/20 13:57)
Впрочем, так выглядит лаконичнее.STRING R1(A10). COMPUTE R1 = CONCAT(STRING(Разбивка_просрочка,F5.0),STRING(Дата_код,F5.0)). SORT CASES BY R1. AGGREGATE /OUTFILE=* MODE=ADDVARIABLES /PRESORTED /BREAK=Разбивка_просрочка Дата_код /RollRate_кол_all=N. COMPUTE R2=Разбивка_просрочка - 1. COMPUTE R3=Дата_код - 1. STRING R4(A10). COMPUTE R4 = CONCAT(STRING(R2,F5.0),STRING(R3,F5.0)). AGGREGATE /OUTFILE=* /PRESORTED /BREAK=R1 /RollRate_кол_all_past=MEAN(RollRate_кол_all). RENAME VARIABLES (R1=R4). MATCH FILES /FILE=main_set /TABLE=* /BY R4. EXECUTE. Из-за наличия или отсутствия MODE=ADDVARIABLES,/OUTFILE=* в AGGREGATE ведет себя по-разному. Это тонкость.
Re: Re: Re: Re: Re2: создается копия рабочего файла - netdim
(2008/11/21 10:14)
Большое спасибо Вам за помощь (и отдельное спасибо за ссылку)! С DATASET открывается столько много возможностей для меня!!! Тонкость прочувствовал, спасибо и за это!, но для себя пока оставил явное определение (чтобы не путаться, пока не достаточно попрактиковался).В итоге код получился следующий: STRING R1(A10). COMPUTE R1 = CONCAT(STRING(Разбивка_просрочка,F5.0),STRING(Дата_код,F5.0)). SORT CASES BY R1. AGGREGATE /OUTFILE=* MODE=ADDVARIABLES /PRESORTED /BREAK=R1 /RollRate_кол_all=N. COMPUTE R2=Разбивка_просрочка - 1. COMPUTE R3=Дата_код - 1. STRING R4(A10). COMPUTE R4 = CONCAT(STRING(R2,F5.0),STRING(R3,F5.0)). DATASET DECLARE key_set. AGGREGATE /OUTFILE=key_set /PRESORTED /BREAK=R1 /RollRate_кол_all_past=MEAN(RollRate_кол_all). DATASET ACTIVATE key_set. RENAME VARIABLES (R1=R4). DATASET ACTIVATE DataSet1. MATCH FILES /FILE=* /TABLE=key_set /BY R4. COMPUTE RR_all=(RollRate_кол_all / RollRate_кол_all_past)*100. VARIABLE LABELS RR_all 'RollRate'. DATASET CLOSE key_set. EXECUTE. PS не подскажите еще про команду EXECUTE.? Я не совсем понимаю смысл ее. Вернее смысл понятен, но ведь по идее как может посчитаться R4, если мы еще не выполнили команду с расчетом R1 R2 R3? Получается что все расчеты будут выполнены и без EXECUTE. Данная команда нужна только для сохранения результатов в рабочий файл??? Спасибо.
Re: Re: Re: Re: Re: Re2: создается копия рабочего файла - KO
(2008/11/21 11:03)
(отредактировано 2008/11/21 11:11:17)
Любая команда-процедура, т.е. команда, считывающая все строки данных, например AGGREGATE, сначала исполняет предшествующие преобразования, т.е. делает то же что EXECUTE. Почитайте начальные главы в Command Syntax Reference.P.S. В конце вашего кода EXECUTE логичнее бы поставить после COMPUTE RR_all, т.к. ни VARIABLE LABELS, ни DATASET CLOSE по своей природе не нуждаются в EXECUTE.
Re: Re: Re: Re: Re: Re: Re2: создается копия рабочего файла - netdim
(2008/11/21 12:24)
Command Syntax Reference сейчас активно читаю (никак для себя понять не мог принцип команды). Сейчас все встало на свои места. Думаю остальной мой код сократится теперь процентов на 15-20 )))Большое спасибо за помощь!
|
|||||
О сайте |