3

In order to prepare the data for plotting I need to add a new row to the data:

I have this dataframe:

df <- data.frame(
  test_id = c(1, 1, 1, 1),
  test_nr = c(1, 1, 1, 1),
  region = c("A", "B", "C", "D"),
  test_value = c(3, 1, 1, 2)
)

  test_id test_nr region test_value
1       1       1      A          3
2       1       1      B          1
3       1       1      C          1
4       1       1      D          2

I would like to add a row to this dataframe so the desired output should be:

  test_id test_nr region test_value
1       1       1      A       3.00
2       1       1      B       1.00
3       1       1      C       1.00
4       1       1      D       2.00
5       1       1   mean       1.75

As you can see: column 1 and column 2 are the same value, column 3 changed to 'mean' and column 4 is the mean of row1-4.

I have tried to use add_row from tibble package which gives an error:

library(dpylr)
library(tibble)

df %>% 
  mutate(mean1 = mean(test_value)) %>% 
  add_row(test_id = test_id[1], test_nr=test_nr[1],region="mean", test_value=mean(test_value))

Error in eval_tidy(xs[[j]], mask) : object 'test_id' not found
TarJae
  • 72,363
  • 6
  • 19
  • 66

3 Answers3

2

You could do

library(dplyr)

df %>%
  add_row(test_id = .$test_id[1], test_nr = .$test_nr[1], region = "mean", test_value = mean(.$test_value))
#>   test_id test_nr region test_value
#> 1       1       1      A       3.00
#> 2       1       1      B       1.00
#> 3       1       1      C       1.00
#> 4       1       1      D       2.00
#> 5       1       1   mean       1.75
stefan
  • 90,330
  • 6
  • 25
  • 51
  • I'm curious. What does the `.$test_id[1]` part of this code mean? I have seen `df[1]` for specifying cols, rows, and specific col x row locations, but I'm not sure what the `.$` bit is about. – Shawn Hemelstrand Feb 12 '22 at 21:08
  • @ShawnHemelstrand The `.` is the so called argument placeholder defined in the `magrittr` package, i.e. the `.` could be used to refer to the dataframe from the last step of a `%>%` pipeline. See https://magrittr.tidyverse.org for more on this and some examples on use cases. – stefan Feb 12 '22 at 21:16
1

Coming in with a base R approach, you can build off of an existing row and then rbind to row bind two objects.

# save a new vector from any row you like
row_to_add <- df[1,] 

# alter the values want one at a time
row_to_add$region <- "mean"
row_to_add$test_value <- mean(df$test_value)

# OR alter them at once if you prefer...
row_to_add[,c("region","test_value")] <- c("mean",mean(df$test_value))

# finally use rbind to add to the bottom of the data.frame
rbind(df,row_to_add)
Evan Friedland
  • 3,062
  • 1
  • 11
  • 25
1

If we want to use the OP's method without calling the .$, use exposition pipe (%$%) from magrittr. This have similarity using the with (from base R)

library(magrittr)
library(dplyr)
df %$%
  add_row(., test_id = first(test_id), test_nr = first(test_nr),
    region = "mean", test_value = mean(test_value))
  test_id test_nr region test_value
1       1       1      A       3.00
2       1       1      B       1.00
3       1       1      C       1.00
4       1       1      D       2.00
5       1       1   mean       1.75
akrun
  • 874,273
  • 37
  • 540
  • 662