Skip to content

Instantly share code, notes, and snippets.

@jonocarroll
Created February 21, 2017 23:52
Show Gist options
  • Save jonocarroll/862f2ff79fcc6487de4b9b4d9f70b349 to your computer and use it in GitHub Desktop.
Save jonocarroll/862f2ff79fcc6487de4b9b4d9f70b349 to your computer and use it in GitHub Desktop.
hack version of dplyr::mutate which preserves custom attributes
mutate_with_attrs <- function(df, ...) {
olddf <- df
newdf <- mutate(df, ...)
newnames <- setdiff(names(attributes(olddf)), names(attributes(newdf)))
sapply(seq_along(newnames), function(x) attr(newdf, newnames[x]) <<- attr(olddf, newnames[x]))
return(newdf)
}
library(dplyr)
mydf <- mtcars
attr(mydf, "a") <- "x"
attr(mydf, "b") <- "y"
str(mydf)
#> 'data.frame': 32 obs. of 11 variables:
#> $ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
#> $ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
#> $ disp: num 160 160 108 258 360 ...
#> $ hp : num 110 110 93 110 175 105 245 62 95 123 ...
#> $ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
#> $ wt : num 2.62 2.88 2.32 3.21 3.44 ...
#> $ qsec: num 16.5 17 18.6 19.4 17 ...
#> $ vs : num 0 0 1 1 0 1 0 1 1 1 ...
#> $ am : num 1 1 1 0 0 0 0 0 0 0 ...
#> $ gear: num 4 4 4 3 3 3 3 4 4 4 ...
#> $ carb: num 4 4 1 1 2 1 4 2 2 4 ...
#> - attr(*, "a")= chr "x"
#> - attr(*, "b")= chr "y"
## no custom attributes
mydf %>% mutate(z = 1) %>% str
#> 'data.frame': 32 obs. of 12 variables:
#> $ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
#> $ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
#> $ disp: num 160 160 108 258 360 ...
#> $ hp : num 110 110 93 110 175 105 245 62 95 123 ...
#> $ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
#> $ wt : num 2.62 2.88 2.32 3.21 3.44 ...
#> $ qsec: num 16.5 17 18.6 19.4 17 ...
#> $ vs : num 0 0 1 1 0 1 0 1 1 1 ...
#> $ am : num 1 1 1 0 0 0 0 0 0 0 ...
#> $ gear: num 4 4 4 3 3 3 3 4 4 4 ...
#> $ carb: num 4 4 1 1 2 1 4 2 2 4 ...
#> $ z : num 1 1 1 1 1 1 1 1 1 1 ...
## preserves custom attributes
mydf %>% mutate_with_attrs(z = 1) %>% str
#> 'data.frame': 32 obs. of 12 variables:
#> $ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
#> $ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
#> $ disp: num 160 160 108 258 360 ...
#> $ hp : num 110 110 93 110 175 105 245 62 95 123 ...
#> $ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
#> $ wt : num 2.62 2.88 2.32 3.21 3.44 ...
#> $ qsec: num 16.5 17 18.6 19.4 17 ...
#> $ vs : num 0 0 1 1 0 1 0 1 1 1 ...
#> $ am : num 1 1 1 0 0 0 0 0 0 0 ...
#> $ gear: num 4 4 4 3 3 3 3 4 4 4 ...
#> $ carb: num 4 4 1 1 2 1 4 2 2 4 ...
#> $ z : num 1 1 1 1 1 1 1 1 1 1 ...
#> - attr(*, "a")= chr "x"
#> - attr(*, "b")= chr "y"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment