Nested apply with vector and dataframe

Hello,

I have the following data below. Essentially, I want to take the value in the vector and compare it against all the values to the corresponding column in terms of position. As an example, 55 would be compared against column x in B_df. All values above or larger than 55 should remain the same while all other values be changed to a 0. The same needs to happen with 44 in A_vec. The final output should be an adjusted dataframe of B_df.

I can write a nested for loop but I would want to do this with one of the apply() functions. I think mapply() would be the right function to use but not entirely sure how you'd specify it. Any help would be appreciated!

set.seed(333)

A_vec <- c(55,44,66,77)

B_df <- data.frame(x = sample(50:59, 10), 
                   y = sample(40:49, 10),
                   z = sample(60:69, 10),
                   aa = sample(70:79, 10))

Is this what you mean?

library(tidyverse)

set.seed(333)

A_vec <- c(55,44,66,77)

B_df <- data.frame(x = sample(50:59, 10), 
                   y = sample(40:49, 10),
                   z = sample(60:69, 10),
                   aa = sample(70:79, 10))

map2_dfc(names(B_df), A_vec, ~ if_else(B_df[[.x]] < .y, 0L, B_df[[.x]])) %>% 
    set_names(names(B_df))
#> # A tibble: 10 x 4
#>        x     y     z    aa
#>    <int> <int> <int> <int>
#>  1    58    46     0    79
#>  2    56    47     0     0
#>  3     0    49     0     0
#>  4    59     0     0    77
#>  5     0     0    68     0
#>  6    57     0    67     0
#>  7     0    45     0    78
#>  8     0    44    69     0
#>  9    55    48    66     0
#> 10     0     0     0     0

Created on 2020-01-31 by the reprex package (v0.3.0)

1 Like

You mentioned in your question about apply family, and tagged dplyr. Andres already gave a solution using tidyverse, so I'm adding two more solutions using base R.

set.seed(seed = 333)

A_vec <- c(55, 44, 66, 77)

B_df <- data.frame(x = sample(x = 50:59,
                              size = 10), 
                   y = sample(x = 40:49,
                              size = 10),
                   z = sample(x = 60:69,
                              size = 10),
                   aa = sample(x = 70:79,
                               size = 10))

# using mapply
as.data.frame(x = mapply(FUN = function(p, q) replace(x = p,
                                                      list = (p <= q),
                                                      values = 0),
                         B_df, A_vec))
#>     x  y  z aa
#> 1  58 46  0 79
#> 2  56 47  0  0
#> 3   0 49  0  0
#> 4  59  0  0  0
#> 5   0  0 68  0
#> 6  57  0 67  0
#> 7   0 45  0 78
#> 8   0  0 69  0
#> 9   0 48  0  0
#> 10  0  0  0  0

# using Map
do.call(cbind.data.frame, Map(f = function(p, q) replace(x = p,
                                                         list = (p <= q),
                                                         values = 0),
                              B_df, A_vec))
#>     x  y  z aa
#> 1  58 46  0 79
#> 2  56 47  0  0
#> 3   0 49  0  0
#> 4  59  0  0  0
#> 5   0  0 68  0
#> 6  57  0 67  0
#> 7   0 45  0 78
#> 8   0  0 69  0
#> 9   0 48  0  0
#> 10  0  0  0  0
1 Like

This is perfect. Thank you so much!

These are helpful. Thank you for providing these additional examples :slight_smile:

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.