hllspwn
hllspwn

Reputation: 35

How can I name several graphics in an iterative form?

I have the following data structure:

id id_name date observation
1    aa    2000     1
1    aa    2001     2
1    aa    2002     1
2    dd    2000     1.5
2    dd    2001     0
2    dd    2002     1

I generate several line plots using the code below:

forvalue i = 1/300 {
    graph twoway line observation date if id == `i', ///
    name("graph_`i'") title("?")
}

My problem is that I don't know how to put the name of each id (contained in the variable id_name) as the title of each graph.

I tried achieving this with a local macro but in Stata I can't define this with an if:

local name = id_name if id == `i'

What I managed to do is the following:

forvalue i = 1/300 {
    sort id date
    local title = id_name 
    graph twoway line observation date if id == `i', ///
    name("graph_`i'") title("`title'")
    drop if id == `i'
}

However, the problem of that is the elimination of the data at each step of the iteration.

If anyone could give me a piece of advice to solve this I would be very grateful.

Upvotes: 0

Views: 75

Answers (2)

Nick Cox
Nick Cox

Reputation: 37208

Here's another way to do it, borrowing shamelessly from @Pearly Spencer's example.

It is sufficient to know about one observation where the name you want to use is stored as the value of id_name. Finding the first or last such observation is easiest.

clear
input id str2 id_name date observation
1    aa    2000     1
1    aa    2001     2
1    aa    2002     1
2    dd    2000     1.5
2    dd    2001     0
2    dd    2002     1
3    bb    2000     1.5
3    bb    2001     0
3    bb    2002     1
end

gen long obsno = _n 

forvalue i = 1 / 3 {
    su obsno if id == `i', meanonly 
    display `"graph twoway line observation date if id == `i', name("graph_`i'") title("`=id_name[r(min)]'")"'
}

Another approach, which is more satisfying because it has more applications later, is to copy the string values in id_name to become the value labels of id. labmask from the Stata Journal will do that. Then looking up the value label is a standard task for an extended macro function.

labmask id, values(id_name) 

forvalue i = 1 / 3 {
    display `"graph twoway line observation date if id == `i', name("graph_`i'") title("`: label (id) `i''")"'
}

Upvotes: 2

user8682794
user8682794

Reputation:

Here's one way to do it:

clear
input id str2 id_name date observation
1    aa    2000     1
1    aa    2001     2
1    aa    2002     1
2    dd    2000     1.5
2    dd    2001     0
2    dd    2002     1
3    bb    2000     1.5
3    bb    2001     0
3    bb    2002     1
end

mata: st_local("idnames", invtokens(st_sdata(., "id_name")'))

local idnames : list uniq idnames
tokenize `idnames'

forvalue i = 1 / 3 {
    display `"graph twoway line observation date if id == `i', name("graph_`i'") title("``i''")"'
}

graph twoway line observation date if id == 1, name("graph_1") title("aa")
graph twoway line observation date if id == 2, name("graph_2") title("dd")
graph twoway line observation date if id == 3, name("graph_3") title("bb")

The advantage of this approach is that you create a list of all id_names (stored in local macro idnames, which you can re-use later if necessary.

Upvotes: 2

Related Questions