I'm trying to solve a data management problem in R.
Suppose my data looks as follows:
id <- c("123", "414", "606")
next.up <- c("414", "606", "119")
is.cond.met <- as.factor(c("FALSE", "FALSE", "TRUE"))
df <- data.frame(id, next.up, is.cond.met)
> df
id next.up is.cond.met
1 123 414 FALSE
2 414 606 FALSE
3 606 119 TRUE
And I'd like to obtain is the following:
id <- c("123", "414", "606")
next.up <- c("414", "606", "119")
is.cond.met <- as.factor(c("FALSE", "FALSE", "TRUE"))
origin <- c("606", "606", "119")
df.result <- data.frame(id, next.up, is.cond.met, origin)
> df.result
id next.up is.cond.met origin
1 123 414 FALSE 606
2 414 606 FALSE 606
3 606 119 TRUE 119
In other words: I want to match each ID to its "origin" when a given condition (is.met) is true. The difficulty I'm having is that this is iterative and hierarchical: to find the origin I may have to go through multiple degrees of separations. the logical steps are illustrated below. I'm really not sure how to tackle this in R.
UPDATE
One of the comments propose a data.frame solution which works for sorted data, as in the minimal example above. In truth, my data is not sorted in such a manner. A better example is as follows:
id <- c("961980", "14788", "902460", "900748", "728912", "141726", "1041190", "692268")
next.up <- c("20090", "655036", "40375164", "40031850", "40368996", "961980", "141726", "760112")
is.cond.met <- c(TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE)
df <- data.frame(id, next.up, is.cond.met, stringsAsFactors = FALSE)
glimpse(df)
Observations: 8
Variables: 3
$ id <chr> "961980", "14788", "902460", "900748", "728912", "141726", "1041190", "692268"
$ next.up <chr> "20090", "655036", "40375164", "40031850", "40368996", "961980", "141726", "760112"
$ is.cond.met <lgl> TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
> df
id next.up is.cond.met
1 961980 20090 TRUE
2 14788 655036 FALSE
3 902460 40375164 FALSE
4 900748 40031850 FALSE
5 728912 40368996 FALSE
6 141726 961980 FALSE
7 1041190 141726 FALSE
8 692268 760112 FALSE
UPDATE 2: the end result should look like this:
> df.end.result
id next.up is.cond.met origin
1 961980 20090 TRUE <NA>
2 14788 655036 FALSE <NA>
3 902460 40375164 FALSE <NA>
4 900748 40031850 FALSE <NA>
5 728912 40368996 FALSE <NA>
6 141726 961980 FALSE 961980
7 1041190 141726 FALSE 961980
8 692268 760112 FALSE <NA>