Unidata - извлекает количество строк из полей с несколькими значениями
Я немного новичок, когда дело доходит до Unidata.
Моя проблема в этом;
У меня много записей с 20 полями. Я хочу извлечь общее количество различных значений, используемых в 1 из этих полей; рассматриваемое поле является многозначным, поэтому данные выглядят как "CSR²STR²CD2" и т. д.
Я хочу вывести в Excel, чтобы данные выглядели примерно так, как показано ниже: они содержат COUNT для каждого значения и сколько раз они появляются в этом поле во всех записях.
Column1 Column2
CSR 234235
STR 987346
CD2 736252
Мне сказали, что я могу достичь этого, используя словарь, который вычисляет это или подпрограмму. Но у меня очень мало технических основ в Unidata, поэтому с чего начать, немного за мной.
2 ответа
Похоже, вам нужен взрывной сорт? Многозначные (MV) поля, хотя они очень удобны в базовом коде, могут быть своего рода болью, с которой приходится иметь дело на языке запросов. Их явно поддерживают, но они не так просты, как данные не из MV. Ключ должен сделать "взрывную" сортировку, которая сгладит поля MV - я думаю, что это создает "виртуальные" строки для каждого из полей MV. Если имеется несколько полей MV, и они правильно связаны друг с другом, они будут связаны друг с другом в виртуальных строках. Однозначные и не связанные поля MV будут дублироваться в каждой из виртуальных строк. Это сложно объяснить, но для вашего вопроса вот пример запроса:
Запрос и результаты:
>sort IAN.TEMP BY.EXP ATB BREAK.ON ATB TOTAL COUNTER ID.SUP DET.SUP
ATB.. COUNT
CD2 3
CD3 3
CD4 2
CSR 3
IAN 2
=====
TOTAL 13
13 records listed
Настройка словаря:
>AE DICT IAN.TEMP ATB COUNTER
< 1 > Top of "ATB" in "DICT IAN.TEMP", 7 lines, 11 characters.
*--: P
001: D
002: 1
003:
004:
005: 5L
006: M <--- This is very important! Must be M (or MV) for BY.EXP to work
007: <--- If there are associated MV fields, this needs to be populated
Bottom.
*--: EX
Quit "ATB" in file "DICT IAN.TEMP" unchanged.
< 2 > Top of "COUNTER" in "DICT IAN.TEMP", 6 lines, 10 characters.
*--: P
001: I
002: 1 <-- This just returns "1" for every row in the output, to help with totals
003:
004:
005: 5R
006: S
Bottom.
*--: EX
Quit "COUNTER" in file "DICT IAN.TEMP" unchanged.
Настройка образца данных:
>AE IAN.TEMP *
4 record(s) selected.
< 1 > Top of "3" in "IAN.TEMP", 1 line, 7 characters.
*--: P
001: CD2▒IAN
Bottom.
*--: EX
Quit "3" in file "IAN.TEMP" unchanged.
< 2 > Top of "1" in "IAN.TEMP", 1 line, 15 characters.
*--: P
001: CSR▒CD2▒CD3▒IAN
Bottom.
*--: EX
Quit "1" in file "IAN.TEMP" unchanged.
< 3 > Top of "4" in "IAN.TEMP", 1 line, 15 characters.
*--: P
001: CSR▒CD2▒CD3▒CD4
Bottom.
*--: EX
Quit "4" in file "IAN.TEMP" unchanged.
< 4 > Top of "2" in "IAN.TEMP", 1 line, 11 characters.
*--: P
001: CD4▒CD3▒CSR
Bottom.
*--: EX
Quit "2" in file "IAN.TEMP" unchanged.
В зависимости от ваших потребностей решение будет отличаться. Например...
Вы можете использовать команду SREFORMAT, чтобы извлечь значения из определенных атрибутов в новый файл, а затем легко получить количество элементов из этого файла. В вашем примере у вас будет элемент CSR с атрибутом 1, содержащий все ключи элементов, которые включают CSR. Тогда вам просто нужен еще один элемент dict для отображения счетчика значений atb1. Это приведет к точному выводу, который вы описали.
Вы можете сделать это программно с помощью кода, подобного следующему.
* Assume a1 looks like CSR]CD2]CSR]CSR]CD2...
VALS = DCOUNT(REC<1>,@VM)
COUNTS = ""
FOR V = 1 TO VALS
LOCATE(REC<1,V>,COUNTS,1;POS) THEN
COUNTS<2,POS> += 1
END ELSE
COUNTS<1,-1> = REC<1,V>
COUNTS<2,-1> = 0
END
NEXT V
* Result in COUNTS:
* A1 = CSR]CD2
* A2 = 3]2
Это соответствует вашему варианту использования?