Add a row to a data frame with n columns filled with one (the same) value dplyr (add_row)

Viewed 643

Imagine you want to add a row to a data frame (with many columns) that is filled with one (the same value), but would not like to hard code it by specifying every column value one by one.

Well there is add_row:

df <- tibble(x = 1:3, y = 3:1)

df %>% add_row(x = 4, y = 0)

However, imagine your data frame has 40 columns and you would like the row to include 40 times "blabla" you would probably avoid to add_row(x = "blabla", y = "blabla", ..., n="blabla").

Or imagine, the first five columns should be filled with "blabla", the next five columns should be filled with "blubblub" and ...

Is there a way avoiding hard coding this?

2 Answers

Adding data rowwise is not preferred generally because each column have different class and adding row of data might mess them up.

To answer your question if you want to add the same value to each row, you can do :

df <- tibble(x = 1:3, y = 3:1)
df[nrow(df) + 1, ] <- 10

This will add a new row in the tibble with all the values as 10.


If you want to add different values without manually writing them by hand you can use rep to repeat certain values n number of times.

To repeat 'blabla' and 'blubblub' 5 times each you can create the vector as

rep(c('blabla', 'blubblub'), each = 5)
#[1] "blabla"   "blabla"   "blabla"   "blabla"   "blabla"  
#[6] "blubblub" "blubblub" "blubblub" "blubblub" "blubblub"

To repeat 'blabla' 5 times and 'blubblub' 4 times you can do :

rep(c('blabla', 'blubblub'), c(5, 4))
#[1] "blabla"   "blabla"   "blabla"   "blabla"   "blabla"   "blubblub"
#[7] "blubblub" "blubblub" "blubblub"

So using rep you can create a vector of your required and create a one-row dataframe with column names same as your original data. Note that a vector can have data of only one type so if you have numbers and characters mixed they will turn numbers to characters. To get the correct classes you can use type.convert after creating one row dataframe.

df <- tibble(x = 1:3, y = 3:1, z = 'a')
other_data <- setNames(data.frame(t(c(rep(10, 2), 'b'))), names(df))
other_data <- type.convert(other_data, as.is = TRUE)
result <- rbind(df, other_data)

Maybe this can help:

library(dplyr)
library(tidyr)
#Data
df <- tibble(x = 1:3, y = 3:1,z=1,a=5,b=3,c=2)
#Code
df %>% bind_rows(data.frame(x = 4, z = 0)) %>%
  mutate(id=row_number()) %>%
  pivot_longer(-id) %>%
  group_by(id) %>%
  fill(value) %>%
  pivot_wider(names_from = name,values_from=value) %>%
  ungroup() %>% select(-id)

Output:

# A tibble: 4 x 6
      x     y     z     a     b     c
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1     1     3     1     5     3     2
2     2     2     1     5     3     2
3     3     1     1     5     3     2
4     4     4     0     0     0     0
Related