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 ID
s 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"],
)
))