0

I want to create a function that takes a simple feature layer and a variable name and creates random points based on the variable values. I can do this without a problem sequentially using pipes(%), but I'm getting stuck on setting up a function using pipes to do the same.

library(tidyverse)
library(sf)
library(tmap)

data("World") # load World sf dataset from tmap

# this works to create a point layer of population by country
World_pts <- World %>% 
  select(pop_est) %>% 
  filter(pop_est >= (10^6)) %>% 
  st_sample(., size = round(.$pop_est/(10^6))) %>% # create 1 random point for every 1 million people
  st_sf(.)

# here's what it looks like
tm_shape(World) + tm_borders() + tm_shape(World_pts) + tm_dots()

# this function to do the same does not work
pop2points <- function(sf, x){
  x <- enquo(x)
  sf %>% 
    select(!!x) %>% 
    filter(!!x >= (10^6)) %>% # works up to here
    st_sample(., size = round(!!.$x/(10^6))) %>% # this is where it breaks
    st_sf(.)
}

World_pts <- pop2points(World,pop_est)

I suspect that I'm getting confused about how to handle non-standard evaluation in a function argument.

Marcos
  • 444
  • 4
  • 9

1 Answers1

1

One option would be converting your x to label and using the .[[ approach for referring to column names:

pop2points <- function(sf, x){
  x <- enquo(x)
  sf %>% 
    select(!!x) %>% 
    filter(!!x >= (10^6)) %>%
    st_sample(., size = round(.[[as_label(x)]] /(10^6))) %>%
    st_sf(.)
}
arg0naut91
  • 14,574
  • 2
  • 17
  • 38
  • 1
    Ha! I was circling around `.[[` for a while but couldn't get past the idea that I had to use the bang-bang `!!` operator. Thanks so much. – Marcos Mar 21 '20 at 16:58