Home > Software engineering >  In R, how can I create a new list-column variable in a tibble that doesn't depend on any prior
In R, how can I create a new list-column variable in a tibble that doesn't depend on any prior

Time:07-07

This seems like a fairly basic question but I'm strugging to solve it. In the simplest form my problem is this: I have a vector of latitudes and a vector of longitudes and I'd like to generate 3 random integers without replacement for each one.

The code I want to make in my head runs something like this:

library(tidyverse)
LAT = c(0, 10, 20, 30, 40)
LON = c(-180, -120, -60, 0, 60, 120)
Case = c("All", "These", "Are", "Arbitrary")

df <- crossing(LAT, LON, Case) %>%
      nest(TotalCases = Case) %>%
      mutate(ViewingAngles = sample(0:50, 3, replace=F))

The 'TotalCases' element there is representative of some of the other irrelevant code I have to do on this dataframe, but the effect is the same - I generate a large (in this case 120x3) tibble that nests down to a 30x3 nested tibble. I'd then like to add another nested list-column to the end on the basis of that Sample function, but the output needs to be generated without replacement (meaning I cannot generate the three values separately) and must be distinct for each lat-lon pair, which means I cannot simply include "ViewingAngles" in my crossing() call.

My first inclination was to use some variant of map but that doesn't work without a .x and none makes sense to me. I also cannot simply use mutate(ViewingAngles = list(sample(0:50,3,replace=F)) because then each lat-lon pair has the same set of ViewingAngles.

Wut Do?

Thanks.

CodePudding user response:

library(tidyverse)


LAT <- c(0, 10, 20, 30, 40)
LON <- c(-180, -120, -60, 0, 60, 120)
Case <- c("All", "These", "Are", "Arbitrary")

# create the dataframe
df <- crossing(LAT, LON, Case) %>%
    nest(TotalCases = Case)

# generate random numbers
lists_numbers <- replicate(nrow(df), sample(0:50, 3, replace = F), simplify = FALSE)

# check whether unique vectors are created for each LON LAT combination
length(unique(as.numeric(sapply(lists_numbers, paste0, collapse = "")))) == nrow(df)
#> [1] TRUE

# create the nested list column
new_df <- df %>%
    mutate(ViewingAngles = lists_numbers)

new_df
#> # A tibble: 30 × 4
#>      LAT   LON TotalCases       ViewingAngles
#>    <dbl> <dbl> <list>           <list>       
#>  1     0  -180 <tibble [4 × 1]> <int [3]>    
#>  2     0  -120 <tibble [4 × 1]> <int [3]>    
#>  3     0   -60 <tibble [4 × 1]> <int [3]>    
#>  4     0     0 <tibble [4 × 1]> <int [3]>    
#>  5     0    60 <tibble [4 × 1]> <int [3]>    
#>  6     0   120 <tibble [4 × 1]> <int [3]>    
#>  7    10  -180 <tibble [4 × 1]> <int [3]>    
#>  8    10  -120 <tibble [4 × 1]> <int [3]>    
#>  9    10   -60 <tibble [4 × 1]> <int [3]>    
#> 10    10     0 <tibble [4 × 1]> <int [3]>    
#> # … with 20 more rows

Created on 2022-07-07 by the reprex package (v2.0.1)

  • Related