Home > Net >  Force the application of the right as_tibble function on an object in a purrr::map call in R
Force the application of the right as_tibble function on an object in a purrr::map call in R

Time:11-15

I am trying to use the fact that as_tibble is a generic function so that I can process a column containing one out of two types of objects in the same way.

The list column temp can store either a list or an object of type AsspDataObj. I can define an as_tibble function for that class

library(dplyr)

as_tibble.AsspDataObj <- function(x,field=1, prefix=NULL,na.zeros=TRUE){
  df <- data.frame(x[[field]])
  if(is.null(prefix)){
    if(is.numeric(field)){
      prefix <- names(x)[field]
    }else{
      prefix <- field
    }
  }

  colnames(df) <- paste(prefix,seq(1,ncol(df),1),sep="_")

  times <- seq(from=attr(x,"startTime"),
               by=1/attr(x,"sampleRate"),
               length.out=nrow(df))
  out <-
    tibble(times_orig=times,
           times_rel=seq(from=0,to=(attr(x,"endRecord")-1)* 1000/attr(x,"sampleRate") ,by=1000/attr(x,"sampleRate")),
           times_norm=times_rel / (max(times_rel) - min(times_rel))
    ) %>%
    dplyr::bind_cols(df)

  if(na.zeros){
    out <- out %>%
      dplyr::mutate(across(!times_orig & !times_rel & !times_norm, ~ na_if(.,0)))
  }
  return(out)
}

and then apply the function to one of the stored objects and get the expected result.

> class(pluck(illustration, "temp",1))
[1] "AsspDataObj"
> as_tibble(pluck(illustration, "temp",1))
# A tibble: 581 × 7
   times_orig times_rel times_norm  fm_1  fm_2  fm_3  fm_4
        <dbl>     <dbl>      <dbl> <int> <int> <int> <int>
 1     0.0025         0    0          NA  1062  2073  3156
 2     0.0075         5    0.00172  1239  2109  3113  4247
 3     0.0125        10    0.00345    NA  1352  2316  3310
 4     0.0175        15    0.00517    NA  1448  2555  3870
 5     0.0225        20    0.00690    NA  1438  2564  3958
 [...]

Now, I want to apply the function to each object, and expand (unnest) the output so that result is actually the as_tibble output columns for each stored AsspDataObj, but joined with the other columns in the illustration data set.

Now, if I do this (and simplify the output a but by removing some columns just for now)

> illustration %>% mutate(out = map(.x = temp,.f=as_tibble)) %>% select(sl_rowIdx,out) %>% unnest(out)

I get this output

# A tibble: 1,162 × 10
   sl_rowIdx frame_time   fm1   fm2   fm3   fm4   bw1   bw2   bw3   bw4
       <int>      <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1         1        2.5     0  1062  2073  3156     0   800   369   890
 2         1        7.5  1239  2109  3113  4247   644   493   792   859
 3         1       12.5     0  1352  2316  3310     0   486   762   933
 4         1       17.5     0  1448  2555  3870     0   577   716  1442
 5         1       22.5     0  1438  2564  3958     0   548   552  1062
 6         1       27.5     0  1343  2518  4001     0   637   617  1096

which is not the output I would expect to see if the as_tibble generic above had been applied. Instead, it seems that some other as_tibble function has been applied to the object.

Why? How do I find out what as_tibble.* function has been applied here? How do I force the application of my definition?

You need a data excerpt https://umeauniversity-my.sharepoint.com/:u:/g/personal/frkkan96_ad_umu_se/ET_56GqikHxAuFc60y_ce1UBL0lOOJcqWaMDjDwLOxjuOw?e=IsEZPf

CodePudding user response:

Sorry, I found the answer. The problem was in the lexical scoping of R (I think) with a (not exported) definition of as_table.AsspDataObj defined in the package where the AsspDataObj was defined

https://github.com/IPS-LMU/wrassp/blob/cbbc6e9fe100f5f32f7b30510f3008c5a5553440/R/AsspDataObj.R#L357

being called instead of my function.

Confusing.

  • Related