Reputation: 57
I have this function that is able to add integers to an existing dataframe. It takes my integers and transposes them as a column into the dataframe. When I add a column of shorter value, the rows will automatically be assigned as 0. When I add another column of longer length, all the existing columns of shorter length add 0s to be the same length as the longest column. For example...
Function
add_peaks <- function(df, vec, colname) {
colname <- title
new_row <- max(nrow(df), length(vec))
new_df <- df[1:new_row, ,drop = FALSE]
new_df[colname] <- c(vec, rep(NA, new_row - length(vec)))
new_df[is.na(new_df)] <- 0
rownames(new_df) <- NULL
new_df
}
Existing dataframe
Apeaks
1
6
5
Integers
Bpeaks = 2 1 6 12 10 5 8
Cpeaks = 2 1
Dpeaks = 4 1 0 9 20 4 18 11 9 6
Updated dataframe
Apeaks Bpeaks Cpeaks Dpeaks
1 2 2 4
6 1 1 1
5 6 0 0
0 12 0 9
0 10 0 20
0 5 0 4
0 8 0 18
0 0 0 11
0 0 0 9
0 0 0 6
Is there a way to edit the function to add a column of the same name, for example "Dpeaks", to the "Dpeaks" column that already exists while adding 0s to the rest of the columns of shorter length? For example...
Dpeaks = 2 1 4
Apeaks Bpeaks Cpeaks Dpeaks
1 2 2 4
6 1 1 1
5 6 0 0
0 12 0 9
0 10 0 20
0 5 0 4
0 8 0 18
0 0 0 11
0 0 0 9
0 0 0 6
0 0 0 2
0 0 0 1
0 0 0 4
Thank you for the help!
Upvotes: 0
Views: 46
Reputation: 389135
You can append the vector if the column is already existing :
add_peaks <- function(df, vec, colname) {
if(colname %in% names(df)) vec <- c(df[[colname]], vec)
new_row <- max(nrow(df), length(vec))
new_df <- df[1:new_row, ,drop = FALSE]
new_df[colname] <- c(vec, rep(NA, new_row - length(vec)))
new_df[is.na(new_df)] <- 0
rownames(new_df) <- NULL
new_df
}
You can test it :
Dpeaks = c(4, 1, 0, 9, 20, 4, 18, 11, 9, 6)
df <- add_peaks(df, Dpeaks, "Dpeaks")
df
# Apeaks Dpeaks
#1 1 4
#2 6 1
#3 5 0
#4 0 9
#5 0 20
#6 0 4
#7 0 18
#8 0 11
#9 0 9
#10 0 6
Dpeaks = c(2, 1, 4)
df <- add_peaks(df, Dpeaks, "Dpeaks")
df
# Apeaks Dpeaks
#1 1 4
#2 6 1
#3 5 0
#4 0 9
#5 0 20
#6 0 4
#7 0 18
#8 0 11
#9 0 9
#10 0 6
#11 0 2
#12 0 1
#13 0 4
Upvotes: 1
Reputation: 887501
If we have access to cbind.fill
from rowr
library(rowr)
cbind.fill(df1, Bpeaks, Cpeaks, Dpeaks, fill = 0)
Or using base R
, keep the vectors in a list
lst1 <- list(Apeaks = df1$Apeaks, Bpeaks = Bpeaks,
Cpeaks = Cpeaks, Dpeaks = Dpeaks)
mx <- max(lengths(lst1))
out <-sapply(lst1, `length<-`, mx)
out[is.na(out)] <- 0
out
# Apeaks Bpeaks Cpeaks Dpeaks
# [1,] 1 2 2 4
# [2,] 6 1 1 1
# [3,] 5 6 0 0
# [4,] 0 12 0 9
# [5,] 0 10 0 20
# [6,] 0 5 0 4
# [7,] 0 8 0 18
# [8,] 0 0 0 11
# [9,] 0 0 0 9
#[10,] 0 0 0 6
df1 <- structure(list(Apeaks = c(1L, 6L, 5L)),
class = "data.frame", row.names = c(NA,
-3L))
Upvotes: 0