Home > Software engineering >  Applying a function using elements within a list
Applying a function using elements within a list

Time:04-06

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.

library(tibble)
library(REdaS)##degrees to radians
library(tidyverse)
data<- list(
  london = tibble(day =c(1,2,3),Average = c(1,3,2),
                Amplitude = c(2,5,6)),
                Glasgow = tibble(day = c(1,2,3),Average = c(1,2,3),
                       Amplitude = c(2,4,6)
))


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
}


I've tried using the map function in purr however have not quite mastered accessing the correct elements of the list for my function, and also had issues with storing the new created values.

Can anybody suggest a simple fix?

Many thanks, Stuart Edit to add my actual data structure: enter image description here enter image description here

CodePudding user response:

So from my understanding, you have a list. So the simplest solution is to use lapply and itterate over every element of said list.

You first itterate over the list:

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

After that (and with some cleaning) you can use the data and plot your curve with ggplot2. Please keep in mind, that I extracted the location and written it to loc, as well as day, which both are used in the plot. Following is the whole code:

library(ggplot2)
data <- lapply(data, function(x){
  sinefunc(Amplitude = x[,"Amplitude"], Average = x[,"Average"])
})
data <- data.frame(unlist(data))
data$loc <- gsub("[^a-zA-Z]", "", rownames(data))
data$day <- gsub("\\D", "", rownames(data))
ggplot(data, aes(x = day, y = unlist.data., color = loc, group = 1))  
  geom_line()

CodePudding user response:

Maybe is this something you had in mind concerning purrr? I changed the example values a bit for the ggplot.

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

data<- list(
  london = tibble(day =c(1,2,3),Average = c(5,3,2),
                  Amplitude = c(5,5,6)),
  Glasgow = tibble(day = c(1,2,3),Average = c(1,2,20),
                   Amplitude = c(2,4,10)
  ))


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 %>% 
  map_dfr(~sinefunc(.x$Average, .x$Amplitude)) %>% 
  mutate(day = row_number()) %>% 
  pivot_longer(cols = -day, names_to = "location", values_to = "value") %>% 
  ggplot(aes(x = day, y = value, color = location))  
  geom_line()
  • Related