1

I am very new to S3 and was wondering if it was possible given the following data frame:

test <- tibble(
  elements = c("one", "two", "three"),
  S3 = c("foo", "bar", "foo")
)

I could give each element in the elements column a custom class from the S3 column:

custom_class <- function(x, customclass) {
  class(x) <- c(class(x), customclass)
  return(x)
}

# test
s <- "string"
custom_class(s, "anything")
test <- tibble(
  elements = c("one", "two", "three"),
  S3 = c("foo", "bar", "foo"),
  testing = custom_class(elements, S3)
)

But this doesn't work. Is this due to a mental model gap in my understanding of S3? Is it possible to apply different classes to each element in this way, and if not maybe create the output as a list in some way so that each element in the list is an element with class S3? Any tips/help advice appreciated!

MayaGans
  • 1,815
  • 9
  • 30
  • I can use `map2(test$elements, test$S3, ~ custom_class(.x, .y))` but can I input that into a datarame without losing the custom classes? – MayaGans Apr 18 '20 at 17:08

2 Answers2

1

By using c on a data frame, all attribute are lost. We can keep any custom attributes by creating a list column within the data frame:

test <- tibble(
  elements = c("one", "two", "three"),
  S3 = c("foo", "bar", "foo"),
  test = map2(elements, S3, ~ custom_class(.x, .y))
)
MayaGans
  • 1,815
  • 9
  • 30
  • While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. – Mustafa Apr 19 '20 at 07:55
  • Thanks for your input @Mustafa, I added a little blurb which I think gets to the point! – MayaGans Apr 19 '20 at 15:30
1

Another option is rowwise if we want to stick with dplyr

library(dplyr)
tibble(
  elements = c("one", "two", "three"),
   S3 = c("foo", "bar", "foo")) %>% 
    rowwise %>%
    mutate(test = list(custom_class(elements, S3)))
# A tibble: 3 x 3
# Rowwise: 
#  elements S3    test      
#  <chr>    <chr> <list>    
#1 one      foo   <charactr>
#2 two      bar   <charactr>
#3 three    foo   <charactr>
akrun
  • 874,273
  • 37
  • 540
  • 662