How to add an integer to an existing dataframe of different column length in r?

Viewed 770

Sorry if this question has been asked already. I am new to R.

I currently have a dataframe with 1 column. I am trying to build this dataframe with different integers I have.

Apeaks
1
6
5

I have the following integers

Bpeaks = 2 1 6 12 10 5 8
Cpeaks = 2 1
Dpeaks = 4 1 0 9 20 4 18 11 9 6

I am trying to add the integer (list of integers?) Bpeaks to the dataframe Apeaks as a column. At the same time, the Apeaks column would only have 3 values while the Bpeaks column will have 7 values. I am trying to assign the value of 0 for each row of Apeaks for the extra # of rows as Bpeaks.

This is what I'm hoping for my result

Apeaks Bpeaks
1      2
6      1
5      6
0      12
0      10
0      5
0      8

In addition, when I add a column of shorter value, the rows will automatically be assigned as 0. For example

Cpeaks = 2 1


Apeaks Bpeaks Cpeaks
1      2      2
6      1      1
5      6      0
0      12     0
0      10     0
0      5      0
0      8      0

And when I add another column of longer length, all the existing columns add a value of 0 for each extra row. For example

Dpeaks = 4 1 0 9 20 4 18 11 9 6

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 any way to do this (code would be very helpful)? Appreciate the help!

2 Answers

Here's an alternative that allows for adding multiple vectors at once. It also includes an option to rename the variable where the vector is going to be added.

add_data <- function(df, ..., names = NULL) {
  l <- list(...)
  if (!is.null(names)) { if (length(names) != length(l)) stop("wrong number of names") }
  if (is.null(names)) names <- sapply(substitute(list(...))[-1], deparse)
  l <- c(c(df), setNames(l, names))
  out <- data.frame(lapply(l, `length<-`, max(lengths(l))))
  replace(out, is.na(out), 0)
}

Here we're adding Bpeaks and Cpeaks, keeping the names of the objects.

add_data(df, Bpeaks, Cpeaks)
#   Apeaks Bpeaks Cpeaks
# 1      1      2      2
# 2      6      1      1
# 3      5      6      0
# 4      0     12      0
# 5      0     10      0
# 6      0      5      0
# 7      0      8      0

Here, we're adding Cpeaks and Dpeaks, but renaming them to "C", and "D".

add_data(df, Cpeaks, Dpeaks, names = c("C", "D"))
#    Apeaks C  D
# 1       1 2  4
# 2       6 1  1
# 3       5 0  0
# 4       0 0  9
# 5       0 0 20
# 6       0 0  4
# 7       0 0 18
# 8       0 0 11
# 9       0 0  9
# 10      0 0  6

You can use this function to add new columns :

add_Data <- function(df, vec) {
   colname <- deparse(substitute(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
}

Bpeaks = c(2, 1, 6, 12, 10, 5, 8)
Cpeaks = c(2, 1)
Dpeaks = c(4, 1, 0, 9, 20, 4, 18, 11, 9, 6)

df <- add_Data(df, Bpeaks)
df

#  Apeaks Bpeaks
#1      1      2
#2      6      1
#3      5      6
#4      0     12
#5      0     10
#6      0      5
#7      0      8

Adding Cpeaks

df <- add_Data(df, Cpeaks)
df
#  Apeaks Bpeaks Cpeaks
#1      1      2      2
#2      6      1      1
#3      5      6      0
#4      0     12      0
#5      0     10      0
#6      0      5      0
#7      0      8      0

Adding Dpeaks :

df <- add_Data(df, Dpeaks)
df
#   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

data

We started off with this dataframe :

df <- structure(list(Apeaks = c(1L, 6L, 5L)), class = "data.frame", 
row.names = c(NA, -3L))
Related