简体   繁体   中英

Make a list element of each group with dplyr's group_by function

I would like to be able to use more automation when creating SpatialLines objects from otherwise tidy data frames.

library(sp)
#create sample data
sample_data <- data.frame(group_id = rep(c("a", "b","c"), 10),
                          x = rnorm(10), 
                          y = rnorm(10))

#How can I recreate this using dplyr?
a_list <- Lines(list(Line(sample_data %>% filter(group_id == "a") %>% select(x, y))), ID = 1)
b_list <- Lines(Line(list(sample_data %>% filter(group_id == "b") %>% select(x, y))), ID = 2)
c_list <- Lines(Line(list(sample_data %>% filter(group_id == "c") %>% select(x, y))), ID = 3)
SpatialLines(list(a_list, b_list, c_list))

You can see how using something like group_by would make the process pretty easy if you could understand how the data could be piped into a list.

Using your sample data, a wrapper function, and dplyr::do will give you what you want :)

wrapper <- function(df) {
  df  %>% select(x,y) %>% as.data.frame %>% Line %>% list %>% return
  }

 y <-  sample_data %>% group_by(group_id) %>%
  do(res = wrapper(.)) 

 # and now assign IDs (since we can't do that inside dplyr easily)
 ids = 1:dim(y)[1]
 SpatialLines(
   mapply(x = y$res, ids = ids, FUN = function(x,ids) {Lines(x,ID=ids)})
 )

I don't use sp so there might be a better way to assign IDs.

For reference, consider reading Hadley's comments on returning non-dataframe from dplyr do calls

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM