Nox
Nox

Reputation: 157

Adding the first non-missing observation across columns

I currently have deviations for a number of models as shown in the data below:

year   model_2015   model_2016   model_2017
2016      15            .           . 
2017      20           10           .
2018      30           20           30

Variable Model_2015, performed in 2015, has deviations for 2016, 2017, 2018; variable Model_2016 for 2017 as well as 2018, and so on.

I would like to create a variable that sums the first observation of each.

So for this example:

first = 15 + 10 + 30 = 55

I'm assuming that I have to make a loop, but I am stumped on how to go about it.


EDIT:

Ideally, I would also like a solution adding the second, third, and so on non-missing observations.

Upvotes: 1

Views: 98

Answers (2)

user8682794
user8682794

Reputation:

The following works for me:

generate first = model_2015[1] + model_2016[2] + model_2017[3]

However, here is a more general approach:

clear

input year   model_2015   model_2016   model_2017
2016      15            .           . 
2017      20           10           .
2018      30           20           30
end

generate id = 1
tempfile myfile
save `myfile'

collapse (firstnm) model*, by(id)
egen first = rowtotal(model*)
keep id first
merge 1:m id using `myfile'

drop id _merge
order year model* first

list, abbreviate(15)

     +-----------------------------------------------------+
     | year   model_2015   model_2016   model_2017   first |
     |-----------------------------------------------------|
  1. | 2016           15            .            .      55 |
  2. | 2017           20           10            .      55 |
  3. | 2018           30           20           30      55 |
     +-----------------------------------------------------+

EDIT:

Below, is an even more general solution:

clear

input year   model_2015   model_2016   model_2017
2016      15            .           . 
2017      20           10           .
2018      30           20           30
2019      40           10           10
end

local i = 0
foreach v of varlist model* {
    local ++i
    local vals
    forvalues j = 1 / `=_N' {
        if !missing(`v'[`j']) local vals `vals' `=`v'[`j']'
    }
    local ind_`i' `: word 1 of `vals'' // CHANGE THIS NUMBER
    local ind_all `ind_all' `ind_`i''
}
generate first = `= subinstr("`ind_all'", " ", "+", `= wordcount("`ind_all'") - 1')'

Results:

list, abbreviate(15)

     +-----------------------------------------------------+
     | year   model_2015   model_2016   model_2017   first |
     |-----------------------------------------------------|
  1. | 2016           15            .            .      55 |
  2. | 2017           20           10            .      55 |
  3. | 2018           30           20           30      55 |
  4. | 2019           40           10           10      55 |
     +-----------------------------------------------------+

     +-----------------------------------------------------+
     | year   model_2015   model_2016   model_2017  second |
     |-----------------------------------------------------|
  1. | 2016           15            .            .      50 |
  2. | 2017           20           10            .      50 |
  3. | 2018           30           20           30      50 |
  4. | 2019           40           10           10      50 |
     +-----------------------------------------------------+

     +-----------------------------------------------------+
     | year   model_2015   model_2016   model_2017   third |
     |-----------------------------------------------------|
  1. | 2016           15            .            .      40 |
  2. | 2017           20           10            .      40 |
  3. | 2018           30           20           30      40 |
  4. | 2019           40           10           10      40 |
     +-----------------------------------------------------+

Note that in this case I used a slightly modified example for better illustration.

Upvotes: 2

Romalpa Akzo
Romalpa Akzo

Reputation: 599

The code below might be the loop(s) that you are seeking for:

forvalues i = 1 / `=_N' {
    generate S_`i' = 0
    forvalues j = `i' / `=_N' {
        capture replace S_`i' = S_`i' + model_`=2015+`j'-`i''[`j']
    }
}

Upvotes: 2

Related Questions