Home > database >  R elementwise calculations in dataframe which contains lists
R elementwise calculations in dataframe which contains lists

Time:06-30

I have the following dataframe df:

           adj_coords
1    2, 3, 4, 5, 6, 7
2   1, 3, 7, 8, 9, 10
3 1, 2, 4, 10, 11, 12
4 1, 3, 5, 12, 13, 14
5 1, 4, 6, 14, 15, 16
6 1, 5, 7, 16, 17, 18
                             adj_coords_material_amounts
1     0.0000, 0.0000, 0.0000, 0.0000, 632.6667, 264.3333
2 263.0000, 0.0000, 264.3333, 262.6667, 0.0000, 238.6667
3   263.0000, 0.0000, 0.0000, 238.6667, 0.0000, 298.3333
4 263.0000, 0.0000, 0.0000, 298.3333, 300.6667, 279.3333
5 263.0000, 0.0000, 632.6667, 279.3333, 0.0000, 273.3333
6   263.0000, 0.0000, 264.3333, 273.3333, 0.0000, 0.0000


df<-structure(list(adj_coords = list(2:7, c(1L, 3L, 7L, 8L, 9L, 10L
), c(1L, 2L, 4L, 10L, 11L, 12L), c(1L, 3L, 5L, 12L, 13L, 14L), 
    c(1L, 4L, 6L, 14L, 15L, 16L), c(1L, 5L, 7L, 16L, 17L, 18L
    )), adj_coords_material_amounts = list(c(0, 0, 0, 0, 632.666666666666, 
264.333333333334), c(263, 0, 264.333333333334, 262.666666666667, 
0, 238.666666666667), c(263, 0, 0, 238.666666666667, 0, 298.333333333333
), c(263, 0, 0, 298.333333333333, 300.666666666667, 279.333333333334
), c(263, 0, 632.666666666666, 279.333333333334, 0, 273.333333333334
), c(263, 0, 264.333333333334, 273.333333333334, 0, 0))), row.names = c(NA, 
6L), class = "data.frame")

I would like to sample one element from each row of adj_coords but only where the corresponding element in adj_coords_material_amounts is >0.

CodePudding user response:

Loop over each paired set of adj_coords and adj_coords__material_amounts using mapply and sample one value with the selection > 0.

##set.seed(1)
mapply(
    \(co,ma) sample(co[ma > 0], 1),
    df[["adj_coords"]], df[["adj_coords_material_amounts"]]
)
#[1]  6 10 12  1  6  1

CodePudding user response:

I am not that familar with dplyr, but below is one of my attempt

df %>%
  mutate(id = 1:n()) %>%
  unnest(c(adj_coords, adj_coords_material_amounts)) %>%
  filter(adj_coords_material_amounts > 0) %>%
  group_by(id) %>%
  slice_sample(n = 1) %>%
  ungroup() %>%
  select(!id)

and you will see

# A tibble: 6 × 2
  adj_coords adj_coords_material_amounts
       <int>                       <dbl>
1          7                        264.
2          8                        263.
3          1                        263
4         14                        279.
5         16                        273.
6          1                        263
  •  Tags:  
  • r
  • Related