Andrew
Andrew

Reputation: 105

Find corresponding "father" row in dataframe

I've a dataframe with A and B rows. Bs are children of A.

For each B line I need to write the corresponding A father.

The number of Bs for each A is variable.

I'm thinking about a for cycle but I don't think it's the right way....

Here a simplified example:

> df <- data.frame(Index=c(1:9),
+                  Type=c("A","B","A","B","B","B","A","B","B"),
+                  Aindex="")
> df
  Index Type Aindex
1     1    A       
2     2    B       
3     3    A       
4     4    B       
5     5    B       
6     6    B       
7     7    A       
8     8    B       
9     9    B       

This is the result I'd like to have:

> df2
  Index Type Aindex
1     1    A       
2     2    B      1
3     3    A       
4     4    B      3
5     5    B      3
6     6    B      3
7     7    A       
8     8    B      7
9     9    B      7

Upvotes: 0

Views: 28

Answers (2)

here in base R cumsum() is really great for this i use it always to find parent child relations

df <- data.frame(Index=c(1:9), Type=c("A","B","A","B","B","B","A","B","B"))
df$parent <- df$Type == "A"
df$aindex <- cumsum(df$parent)
df$aindex[df$Type == "A"] <- ""
df$aindex[df$aindex > 0] <- df$Index[df$Type == "A"][as.numeric(df$aindex[df$aindex > 0])]

result

  Index Type parent aindex
1     1    A   TRUE       
2     2    B  FALSE      1
3     3    A   TRUE       
4     4    B  FALSE      3
5     5    B  FALSE      3
6     6    B  FALSE      3
7     7    A   TRUE       
8     8    B  FALSE      7
9     9    B  FALSE      7

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 389215

You can use tidyr::fill :

library(dplyr)
library(tidyr)

df %>%
  #Turn Aindex to NA if type = 'B'
  mutate(Aindex = replace(Index, Type == 'B', NA)) %>%
  #fill NA with value above it
  fill(Aindex) %>%
  #Change the Aindex to empty value where Type = 'A'
  mutate(Aindex = replace(Aindex, Type == 'A', ''))

#  Index Type Aindex
#1     1    A       
#2     2    B      1
#3     3    A       
#4     4    B      3
#5     5    B      3
#6     6    B      3
#7     7    A       
#8     8    B      7
#9     9    B      7

Upvotes: 1

Related Questions