Rtist
Rtist

Reputation: 4205

In R, adding a new row to dataframe, to each id

I have the following dataframe:

df = data.frame(id = rep(101:110, each = 2),
                variable = rep(c('a','b'), times = 2),
                score = rnorm(1)) 

For each id, I want to add the value 'c' in 'variable', and 100 to 'score'. The only way I found is using rbind.

df_helper = data.frame(id = unique(df$id),
                       variable = 'c',
                       score = 100)

rbind(df, df_helper)  

This is not very elegant as I need to define another dataframe. Any better idea?

Upvotes: 0

Views: 328

Answers (2)

akrun
akrun

Reputation: 886948

We can just use bind_rows

library(tidyverse)
bind_rows(df, df_helper)

If there is no 'df_helper' dataset, one way is

df %>% 
    group_by(id) %>% 
    nest %>% 
    mutate(data = map(data, ~ 
                      .x %>% 
                        bind_rows(tibble(variable = "c", score = 100)))) %>%
    unnest
# A tibble: 30 x 3
#      id variable    score
#   <int> <chr>       <dbl>
# 1   101 a          -0.778
# 2   101 b          -0.778
# 3   101 c         100    
# 4   102 a          -0.778
# 5   102 b          -0.778
# 6   102 c         100    
# 7   103 a          -0.778
# 8   103 b          -0.778
# 9   103 c         100    
#10   104 a          -0.778
# ... with 20 more rows

Or another option with `data.table. Grouped by 'id', concatenate the 'c' and 100 respectively to each of the columns at the end

library(data.table)
setDT(df)[, .(variable = c(variable, 'c'), score = c(score, 100)), by = id]

Upvotes: 0

moodymudskipper
moodymudskipper

Reputation: 47300

The tidyverse way would be:

library(tidyverse)
df %>% 
  spread(variable,score) %>%
  mutate(c = 100) %>%
  gather(variable,score, - id)
# id variable       score
# 1  101        a  -0.1831428
# 2  102        a  -0.1831428
# 3  103        a  -0.1831428
# 4  104        a  -0.1831428
# 5  105        a  -0.1831428
# 6  106        a  -0.1831428
# 7  107        a  -0.1831428
# 8  108        a  -0.1831428
# 9  109        a  -0.1831428
# 10 110        a  -0.1831428
# 11 101        b  -0.1831428
# 12 102        b  -0.1831428
# 13 103        b  -0.1831428
# 14 104        b  -0.1831428
# 15 105        b  -0.1831428
# 16 106        b  -0.1831428
# 17 107        b  -0.1831428
# 18 108        b  -0.1831428
# 19 109        b  -0.1831428
# 20 110        b  -0.1831428
# 21 101        c 100.0000000
# 22 102        c 100.0000000
# 23 103        c 100.0000000
# 24 104        c 100.0000000
# 25 105        c 100.0000000
# 26 106        c 100.0000000
# 27 107        c 100.0000000
# 28 108        c 100.0000000
# 29 109        c 100.0000000
# 30 110        c 100.0000000

Upvotes: 1

Related Questions