1
library(dplyr)

Sample data

  df <- data.frame(year = rep(1981:1982, each = 365), doy = rep(1:365, times = 2),
                   tmean = sample(20:35, 730, replace = T), ref.doy = rep(c(60, 80), each = 365))

  thermal.df <- data.frame(stage1 = 60, stage2 = 90, stage3 = 120)

I have a function

  my.function <- function(tmean.ref, doy.ref, thermal.df){

    tm <- tmean.ref[1:length(tmean.ref) >= doy.ref]
    tbase <- 10; topt <- 31;tcri <- 40

    fT <- ifelse(tm >= tbase & tm <= topt,(tm - tbase)/(topt - tbase), ifelse(topt <= tm & tm <= tcri,(tcri - tm)/(tcri - topt), 0))
    thermal.units <- tbase + fT*(topt - tbase)

    stage1 <- as.numeric(thermal.df[, "stage1"])
    stage2 <- as.numeric(thermal.df[, "stage2"])
    stage3 <- as.numeric(thermal.df[, "stage3"])

    pheno <- list(stage1, stage2, stage3)
    return(pheno)
  }

Applying function to df

  df %>% dplyr::group_by(year) %>% 
  dplyr::summarise(x = paste(my.function(tmean.ref = tmean, 
                                         doy.ref = unique(ref.doy), 
                                         thermal.df = thermal.df),collapse = ","))

This returns my outputs in a singe column

  # A tibble: 2 x 2
      year x        
    <int> <chr>    
  1  1981 60,90,120
  2  1982 60,90,120

whereas I want my output as:

   year  stage1 stage2 stage3
   1981   60     90     120
   1982   60     90     120
89_Simple
  • 3,393
  • 3
  • 39
  • 94
  • 2
    Ideal way would be to re-evaluate your function and write it differently, but a quick and dirty fix would be to add `...%>% separate(x, into = c(paste0('stage', seq(3))), sep = ',')` – Sotos Sep 28 '18 at 07:56
  • you basically want to [split the comma separated value into different columns](https://stackoverflow.com/questions/8464312/convert-comma-separated-entry-to-columns) ? – Ronak Shah Sep 28 '18 at 08:01
  • @Sotos That is good but the issue is the number of stages in the function might change. So I need something that splits the x depending on number of elements it has after the functions has run i.e. I do not know a priori the number that should go in `seq(3)` – 89_Simple Sep 28 '18 at 08:04
  • The link provided by Ronak has many ways to do that - my personal favourite is [the splitstackshape one](https://stackoverflow.com/a/26825460/5635580). Although you only define 3 stages in your function (or is that just an example for demonstration) – Sotos Sep 28 '18 at 08:07
  • 1
    Just modify the code used to wrap your function call : `df %>% dplyr::group_by(year) %>% dplyr::summarise(x = list(my.function(tmean.ref = tmean, doy.ref = unique(ref.doy), thermal.df = thermal.df))) %>% unnest %>% unnest %>% group_by(year) %>% mutate(k=paste0("k",row_number())) %>% spread(k,x)` – Nicolas2 Sep 28 '18 at 08:29
  • @Sotos three stages are just for the example – 89_Simple Sep 28 '18 at 08:52

0 Answers0