Add new rows based on computations of other rows in R

Suppose I have a simple dataframe like the following:

ID     number
A1       5
A2       10
B1       7
C4       3
D8       2

I have to perform some maintenance on the dataframe by adding new rows based on either the exact values of another row, or a computation of multiple. For example, if I need to create the following rows:

ID=B2, number= B1's number
ID=C7, number= C4's number
ID=A3, number= (A1's number+A2's number)/2
ID=C9, number= A2's number

adding these rows to the dataframe would yield the following:

ID     number
A1       5
A2       10
B1       7
C4       3
D8       2
B2       7
C7       3
A3      7.5
C9      10

How can I create these new rows computing values from within the dataframe and adding the new IDs in the ID column? Preferably, this would be scaleable, so I can generate as many new rows as possible, according to my formulas, and it would be desirable to use dplyr or tidyverse.

>Solution :

Create a new data frame and then stack it under the original. If this is to be hand-coded (as there appears to be no programmable pattern) I like the tribble() function for creating tables by row:

library(tibble)
# ID=B2, number= B1's number
# ID=C7, number= C4's number
# ID=A3, number= (A1's number+A2's number)/2
# ID=C9, number= A2's number
rbind(df, 
  tribble(
    ~ID, ~number,
    "B2", df[df$ID == "B1", "number"],
    "C7", df[df$ID == "C4", "number"],
    "A3", (df[df$ID == "A1", "number"] + df[df$ID == "A2", "number"]) / 2,
    "C9", df[df$ID == "A2", "number"],
  )
)
#   ID number
# 1 A1    5.0
# 2 A2   10.0
# 3 B1    7.0
# 4 C4    3.0
# 5 D8    2.0
# 6 B2    7.0
# 7 C7    3.0
# 8 A3    7.5
# 9 C9   10.0

You can use with() with the above approach to save quite a bit of typing:

with(df, rbind(df, 
  tribble(
    ~ID, ~number,
    "B2", number[ID == "B1"],
    "C7", number[ID == "C4"],
    "A3", (number[ID == "A1"] + number[ID == "A2"]) / 2,
    "C9", number[ID == "A2"],
  )
))

Leave a Reply