Rename multiple series using string functions

For questions regarding programming in the EViews programming language.

Moderators: EViews Gareth, EViews Moderator, EViews Jason, EViews Matt

adelmann
Posts: 3
Joined: Tue Nov 12, 2019 5:48 am

Rename multiple series using string functions

Postby adelmann » Tue Nov 12, 2019 8:10 am

Dear EViews community,

I am fetching series from eurostat that end up having long names. Example:

Code: Select all

wfcreate a 1985 2017 fetch(d=eurostat) env_air_gge__airemsect=crf1-6x4_memo.airpol=ghg.freq=a.geo=lu.unit=ths_t env_air_gge__airemsect=crf1-6xmemo.airpol=ghg.freq=a.geo=lu.unit=ths_t env_air_gge__airemsect=crf1-6x4_memonia.airpol=ghg.freq=a.geo=lu.unit=ths_t
will give me following names:
  • env_air_gge__airemsect_crf1_6x4_memo_airpol_ghg_freq_a_geo_lu_unit_ths_t env_air_gge__airemsect_crf1_6x4_memonia_airpol_ghg_freq_a_geo_lu_unit_ths_t env_air_gge__airemsect_crf1_6xmemo_airpol_ghg_freq_a_geo_lu_unit_ths_t
I would like to extract the string between "airemsect" and "airpol" (in this case "crf1_6x4_memo", "crf1_6x4_memonia" and "crf1_6xmemo"). So far I have come up with following for the "crf1_6x4_memo" example:

Code: Select all

@mid("env_air_gge__airemsect_crf1_6x4_memo_airpol_ghg_freq_a_geo_lu_unit_ths_t", @instr("env_air_gge__airemsect_crf1_6x4_memo_airpol_ghg_freq_a_geo_lu_unit_ths_t", "airemsect_") + @length("airemsect_"), @length("env_air_gge__airemsect_crf1_6x4_memo_airpol_ghg_freq_a_geo_lu_unit_ths_t") - ( @length("env_air_gge__airemsect_crf1_6x4_memo_airpol_ghg_freq_a_geo_lu_unit_ths_t") - @instr("env_air_gge__airemsect_crf1_6x4_memo_airpol_ghg_freq_a_geo_lu_unit_ths_t", "_airpol") + @instr("env_air_gge__airemsect_crf1_6x4_memo_airpol_ghg_freq_a_geo_lu_unit_ths_t", "airemsect_") + @length("airemsect_") ))
which gives me the expected "crf1_6x4_memo" string.
Note that I cannot use @mid starting at crf1 and indicate a fix number as the string I want to extract changes length from object to object.

Now I would like to use the code above with temporary strings and values so I can use it in a loop, something in the lines of:

Code: Select all

%listseries = @wlookup("*","series") group g1 {%listseries} 'avoid grouping resid and alpha objects for !i=1 to g1.count %strname = "g1.@seriesname(!i)" %name = g1.@seriesname(!i) !left =@instr({%strname}, "airemsect_") + @length("airemsect_") !right = @length({%strname}) - @instr({%strname}, "_airpol") %airemsect = "@mid({%strname}, {!left}, @length({%strname}) - ({!right} + {!left}))" rename {%name} ghg_{%airemsect}_lu next delete g1
However the "@instr({%strname}, "airemsect_")" part in the code above will give me "0" instead of the expected "14". "@instr({%strname}, "airemsect_")" is suppose to replicate follwoing command in the case of "crf1_6x4_memo"

Code: Select all

@instr("env_air_gge__airemsect_crf1_6x4_memo_airpol_ghg_freq_a_geo_lu_unit_ths_t", "airemsect_")
So my loop renames the first object "ghg__lu" instead "ghg_crf1_6x4_memo_lu" and afterwards stops, because it cannot rename the second object the same name as it already exits.
In my example of 3 objects, it would of course be much faster to rename manually, but I intend on using the loop for many objects.

Could someone please have a look at my code and tell me where I am doing the mistake?

Thank you very much.

EViews Gareth
Fe ddaethom, fe welon, fe amcangyfrifon
Posts: 13604
Joined: Tue Sep 16, 2008 5:38 pm

Re: Rename multiple series using string functions

Postby EViews Gareth » Tue Nov 12, 2019 8:37 am

@instr(%strname

adelmann
Posts: 3
Joined: Tue Nov 12, 2019 5:48 am

Re: Rename multiple series using string functions

Postby adelmann » Wed Nov 13, 2019 6:00 am

Dear Gareth,

Unfortunately your solution only works when applied to the example I gave, but not when I try it within a group, in other words:

Code: Select all

%strname= "env_air_gge__airemsect_crf1_6x4_memo_airpol_ghg_freq_a_geo_lu_unit_ths_t" @instr(%strname, "airemsect_")
will give me the desired result "14"; but if I group my series together by

Code: Select all

%listseries = @wlookup("*","series") group g1 {%listseries}
and then run:

Code: Select all

%strname= "g1.@seriesname(1)" @instr(%strname, "airemsect_")
I get as result "0". Interestingly this code will execute correctly:

Code: Select all

%strname = "g1.@seriesname(1)" @length({%strname})
giving me the correct result "72". The code above is the reason I put curly brackets around "%strname". I attached my workfile to facilitate reproducing my problem.

Is there a reason why the @length function works with the group and the @instr does not?

Best regards.
Attachments
renaming.WF1
(16.23 KiB) Downloaded 366 times

EViews Matt
EViews Developer
Posts: 583
Joined: Thu Apr 25, 2013 7:48 pm

Re: Rename multiple series using string functions

Postby EViews Matt » Wed Nov 13, 2019 5:08 pm

Hello,

You have the right idea, but there's a good deal of unnecessary quotation and substitution in your code. We can simplify the syntax of the body of your for loop as follows:

Code: Select all

%name = g1.@seriesname(!i) !left = @instr(%name, "AIREMSECT_") + @length("AIREMSECT_") !right = @instr(%name, "_AIRPOL") %airemsect = @mid(%name, !left, !right - !left) rename %name ghg_{%airemsect}_lu
Most importantly, you'll note that I've changed your search string literals to uppercase. The series names returned by function @wlookup are in uppercase, and function @instr performs case-sensitive string matching. As originally written, your calls to @instr would always return 0.

adelmann
Posts: 3
Joined: Tue Nov 12, 2019 5:48 am

Re: Rename multiple series using string functions

Postby adelmann » Mon Nov 25, 2019 1:38 am

Dear Matt,

Sorry for the late reply.
Thank you very much for pointing out that the @instr function is case-sensitive, I was not aware of this. My code works now like a charm :)

For those reading this now: be aware that my initial fetch command does not work anymore. The filters of the "env_air_gge" dataset has changed from

Code: Select all

fetch(d=eurostat) env_air_gge__airemsect=crf1-6x4_memo.airpol=ghg.freq=a.geo=lu.unit=ths_t
to

Code: Select all

fetch(d=eurostat) env_air_gge__airpol=ghg.freq=a.geo=lu.src_cfr=crf1-6x4_memo.unit=ths_t

Furthermore the fetch command for me (EViews 11) only works for the first object in the object list, but won't find the other objects. So I wrote a loop to fetch one object at a time. For this example:

Code: Select all

'create temporary crf list %crf = "CRF1-6XMEMO CRF1-6X4_MEMO CRF1-6X4_MEMONIA" 'create temporary string values for parts that do not change %begin = "env_air_gge__airpol=ghg.freq=a.geo=lu.src_cfr=" %end = ".unit=ths_t" 'loop to fetch data one after the other for %s {%crf} %fetchname =%begin+%s+%end fetch(d=eurostat) %fetchname next
The final code to fetch the data and rename it, is as follows:

Code: Select all

'create workfile wfcreate a 1985 2017 'create temporary crf list %crf = "CRF1-6XMEMO CRF1-6X4_MEMO CRF1-6X4_MEMONIA" 'create temporary string values for parts that do not change %begin = "env_air_gge__airpol=ghg.freq=a.geo=lu.src_cfr=" %end = ".unit=ths_t" 'loop to fetch data one after the other for %s {%crf} %fetchname =%begin+%s+%end fetch(d=eurostat) %fetchname next 'create list containing ghg data, then rename data %listseries = @wlookup("*_ghg_*","series") group _ghg {%listseries} for !i=1 to _ghg.count %name = _ghg.@seriesname(!i) !left = @instr(%name, "SRC_CFR_") + @length("SRC_CFR_") !right = @instr(%name, "_UNIT") %src_cfr = @mid(%name, !left, !right - !left) rename %name ghg_{%src_cfr}_lu next
I have attached the corresponding program and workfile. Being new to EViews, it is possible that there is an easier / more beautiful way of doing what I am doing. Any improvements of my code are highly appreciated and welcome :)

Best regards.
Attachments
fetch_rename_multiple_series.wf1
(14.76 KiB) Downloaded 368 times
fetch_rename_multiple_series.prg
(747 Bytes) Downloaded 455 times


Return to “Programming”

Who is online

Users browsing this forum: No registered users and 2 guests