Search code examples
rdimensionacross

across dimension computation


I am trying this but do not get why I have an error. I tried even to use some formulas like

fA <- EltA~EltA1+EltA2

but I had some errors

geo <- c("AT","BE","CZ","DE")
time <- c(2020, 2020, 2021,2021)
EltA1 <- c(150, NA, 120,NA)
EltA2 <- c(60, 70, 80,NA)
EltA <- c(210,110,200,8200)

test <- data.frame(geo, time, EltA1, EltA2, EltA)

left_side <- "EltA"
right_side <- c("EltA1","EltA2")


test <- test %>% 
  rowwise() %>%
  mutate(right = sum(c_across(any_of(right_side)),na.rm = TRUE)) %>%
  ungroup() 

test <- test %>% 
  mutate(across(all_of(right_side),
                ~ if(is.na(.x) & (right == left_side)) replace_na(.x,0) else .x))

Any clue?


Solution

  • The function if is not vectorized and thus you should have the message error "condition of length > 1". To change this, we can use ifelse which is vectorized.

    Also, with left_side, I think you want to compare right with column EltA. You can use rlang to do that. I'm not that familiar with rlang, but I used function !! with EltA converted to symbol which seems to do the trick.

    Here is my code :

    library(tidyverse)
    library(rlang)
    
    test <- data.frame(geo, time, EltA1, EltA2, EltA)
    left_side <- "EltA"
    right_side <- c("EltA1","EltA2")
    test <- test %>% 
        rowwise() %>%
        mutate(right = sum(c_across(any_of(c(right_side, left_side))),na.rm = TRUE)) %>%
        ungroup() 
    test %>% 
        mutate(across(all_of(right_side),
                      ~ ifelse(is.na(.x) & (right == !!sym(left_side)), replace_na(.x,0), .x)))
    

    With the result :

    # A tibble: 4 × 6
      geo    time EltA1 EltA2  EltA right
      <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
    1 AT     2020   150    60   210   420
    2 BE     2020    NA    70   110   180
    3 CZ     2021   120    80   200   400
    4 DE     2021     0     0  8200  8200