0
votes

I want to write two functions myself and apply these functions to nested data.

The task of the first function is to access the data of the nested data (name: GROSS), use the values as input, calculate with them and write them back in the same structure as the GROSS column. The result is to be stored in a new column (name TEST01).

The second function should subtract the values from TEST01 from GROSS.

My problem is that functions can only write back one value at a time (correct?) and for this reason I use a LIST as output. So it happens that I have a list in a list as result and not a tibble in a list as desired. How can I adjust the result?

Here is an example:

library(tidyverse)
library(purrr)

df <- as_tibble(matrix(c("A1000", 2016, 2016, 1000, 800, 200, 
"A1000", 2016, 2017, 50, 100, -50, "A1000", 2016, 2018, 0, -40, 40, 
"A1001", 2016, 2016, 500, 0, 500, "A1002", 2017, 2017, 2000,0, 2000, 
"A1002", 2017, 2018, 0, -3000, -3000), nrow = 6, byrow = TRUE, 
dimnames = list(NULL, c("Contract", "Year", "AccoutingYear", "Income", "Costs", "Result"))))%>% 

mutate(Contract = as.factor(Contract), 
       Income   = as.numeric(Income), 
       Costs    = as.numeric(Costs),
       Result   = as.numeric(Result)) %>%

nest(GROSS = c(AccoutingYear, Income, Costs, Result))

T_FUN <- function(df, Quota = 0.4, Provision = 0.2) {
return(list(
            AccoutingYear = df$AccoutingYear, 
            Income    = as.numeric(df$Income * Quota),
            Costs     = as.numeric(df$Costs  * Quota), 
            Provision = as.numeric(df$Income * Quota * Provision)))
}

df %>% mutate(TEST01 = map(.x = GROSS, Quota = 0.3, Provision = 0.25,.f = T_FUN))

For the second function I lack any idea for an approach.

Does anyone know of a possible solution? Many thanks in advance. Tobias

1

1 Answers

0
votes

There is no problem with having T_FUN returning a tibble instead of a list. It was a bit difficult figuring out exactly what you were trying to accomplish, but it sounds like that you're looking for a way of iterating over two lists of dataframes in parallel. One way of doing that is with map2 from purrr. You could try something like this:

T_FUN <- function(df, Quota = 0.4, Provision = 0.2) {
  return(tibble(
    AccountingYear = df$AccountingYear,
    Income = as.numeric(df$Income * Quota),
    Costs = as.numeric(df$Costs * Quota),
    Provision = as.numeric(df$Income * Quota * Provision)
  ))
}

R_FUN <- function(df1, df2) {
  inner_join(df1, df2, by = "AccountingYear") %>% 
    summarise(
      AccountingYear,
      Income = Income.x - Income.y,
      Costs = Costs.x - Costs.y,
      Provision = Result - Provision
    )
}

df %>% 
  mutate(
    TEST01 = map(.x = GROSS, Quota = 0.3, Provision = 0.25, .f = T_FUN),
    RESU01 = map2(GROSS, TEST01, R_FUN)
  ) %>% 
  pull(RESU01)

#> [[1]]
#> # A tibble: 3 x 4
#>   AccountingYear Income Costs Provision
#>   <chr>           <dbl> <dbl>     <dbl>
#> 1 2016              700   560     125  
#> 2 2017               35    70     -53.8
#> 3 2018                0   -28      40  
#> 
#> [[2]]
#> # A tibble: 1 x 4
#>   AccountingYear Income Costs Provision
#>   <chr>           <dbl> <dbl>     <dbl>
#> 1 2016              350     0      462.
#> 
#> [[3]]
#> # A tibble: 2 x 4
#>   AccountingYear Income Costs Provision
#>   <chr>           <dbl> <dbl>     <dbl>
#> 1 2017             1400     0      1850
#> 2 2018                0 -2100     -3000

Created on 2021-05-25 by the reprex package (v1.0.0)