mapping a simple calculation over rows and lists using dplyr

If you're not restricted to using those specific packages, a base R solution could be to use

> lapply(lst1, function(df) do.call(cbind, lapply(df, function(col) {
    col[3] <- ifelse(col[2]==1, -col[3], col[3])
    return (col)
})))
# 
# $`2013 Jul`
#              AAPL         AMD           ADI         ABBV           A
# [1,] 0.0006825655 0.003136999  0.0002099237 0.0008657568 0.001616315
# [2,] 2.0000000000 5.000000000  1.0000000000 2.0000000000 4.000000000
# [3,] 0.0000000000 0.200000000 -0.2000000000 0.0000000000 0.000000000
#              APD           AA           CF        NVDA         HOG
# [1,] 0.001691779 -0.000319519 0.0009616386 0.001586042 0.001514241
# [2,] 5.000000000  1.000000000 3.0000000000 4.000000000 3.000000000
# [3,] 0.200000000 -0.200000000 0.0000000000 0.000000000 0.000000000
#                WMT        AMZN
# [1,]  2.652299e-06 0.001247779
# [2,]  1.000000e+00 3.000000000
# [3,] -2.000000e-01 0.000000000
# ...

which loops over all data frames of in lst1, subsequently loops over all columns in each data frame and changes the third row according to the second row value.


You can do:

map(lst1, ~ .x %>%
     mutate_all(~ if_else(row_number() == 3 & lag(.) == 1, . * -1, .)))

$`2013 Jul`
# A tibble: 3 x 12
      AAPL     AMD     ADI    ABBV       A     APD       AA       CF    NVDA     HOG
     <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>    <dbl>    <dbl>   <dbl>   <dbl>
1 -0.00252 0.00385 3.14e-4 0.00148 2.31e-4 6.55e-4 -0.00107 -0.00137 8.86e-4 8.06e-4
2  1       5       2.00e+0 5       2.00e+0 3.00e+0  1        1       4.00e+0 4.00e+0
3 -0.2     0.2     0.      0.2     0.      0.      -0.2     -0.2     0.      0.     
# … with 2 more variables: WMT <dbl>, AMZN <dbl>

An option with case_when and map

library(purrr)
library(dplyr)
map(lst1, ~ .x %>%  
           mutate_all(~
         case_when(row_number() == 3 & lag(.)== 1 ~ -1 * ., TRUE ~ .)))

Tags:

R