'Applying a function using elements within a list take 2

I attempted this question yesterday(Applying a function using elements within a list) but my reprex produced the wrong data structure and unfortunately the suggestions didn't work for my actual dataset.

I have what is hopefully a simple functional programming question. I have a list of locations with average temperature and amplitude for each day (180 days in my actual dataset). I want to iterate through these locations and create a sine curve of 24 points using a custom made function taking the average temperature and amplitude from each day within a list. Below is my new reprex.

library(tibble)
library(REdaS)##degrees to radians
library(tidyverse)


sinefunc<- function(Amplitude,Average){
  hour<- seq(0,23,1)
  temperature<-vector("double",length = 24)
  
  for(i in seq_along(hour)){
    temperature[i]<- (Amplitude*sin(deg2rad(180*(hour[i]/24)))+Average)+Amplitude*sin(deg2rad(180*hour[i]/12))
  }
  temperature
}

data<- tibble(Location = c(rep("London",6),rep("Glasgow",6),rep("Dublin",6)),
              Day= rep(seq(1,6,1),3),
              Average = runif(18,0,20),
              Amplitude = runif(18,0,15))%>%
  nest_by(Location)

Using Purrr and map_dfr I get the error Error in .x$Average : $ operator is invalid for atomic vectors

df<-data %>% 
  map_dfr(~sinefunc(.x$Average, .x$Amplitude))

Using lapply I get the error Error in x[, "Amplitude"] : incorrect number of dimensions

data <- lapply(data, function(x){
  sinefunc(Amplitude = x[,"Amplitude"], Average = x[,"Average"])
})  

My goal is to have 24 hourly data points for each day and location. Any further help would be much appreciated. Stuart



Solution 1:[1]

Maybe you look for this? You get a dataframe back with 24 datapoints for each day and location, e.g. London-Day1, Dublin-Day1 etc.

library(dplyr)
library(purrr)
data<- tibble(Location = c(rep("London",6),rep("Glasgow",6),rep("Dublin",6)),
              Day= rep(seq(1,6,1),3),
              Average = runif(18,0,20),
              Amplitude = runif(18,0,15))

# get group name
group_name <- data %>% 
  group_by(Location, Day) %>% 
  group_keys() %>%
  mutate(group_name = stringr::str_c(Location,"_",Day)) %>% 
  pull(group_name)


data %>% 
  # split into lists
  group_split(Location, Day) %>%
  # get list name
  setNames(group_name) %>% 
  # apply your function and get a dataframe back
  map_dfr(~sinefunc(.x$Average, .x$Amplitude))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1