Home > Mobile >  Function to assign names to multiple list elements
Function to assign names to multiple list elements

Time:05-17

I have a list of data frames int1 and int2. The end goal of this code is to assign the names to the elements in int1 and int2. The rest of the workflow for my work requires me to name the elements of the list multiple times, and I was wondering how I could create a function to reduce the number of keystrokes down the line using base r functions. Any ideas?

library(lubridate)
library(tidyverse)
library(purrr)

date <- rep_len(seq(dmy("01-01-2011"), dmy("31-07-2011"), by = "days"), 200)
ID <- rep(c("A","B", "C"), 200)
df <- data.frame(date = date,
                 x = runif(length(date), min = 60000, max = 80000),
                 y = runif(length(date), min = 800000, max = 900000),
                 ID)

df$Month <- month(df$date)

# Create first list
int1 <- df %>%
  # arrange(ID) %>%   # skipped for readability of result
  mutate(new = floor_date(date, '10 day')) %>%
  mutate(new = if_else(day(new) == 31, new - days(10), new)) %>% 
  group_by(ID, new) %>%
  filter(Month == "1") %>% 
  group_split()

# Create second list
int2 <- df %>%
  # arrange(ID) %>%   # skipped for readability of result
  mutate(new = floor_date(date, '10 day')) %>%
  mutate(new = if_else(day(new) == 31, new - days(10), new)) %>% 
  group_by(ID, new) %>%
  filter(Month == "2") %>% 
  group_split()

# Expected Output

# Assign names to int1
names(int1) <- sapply(int1, function(x) paste(x$ID[1],
                                              x$new[1], sep = "_"))
# Assign names to int2
names(int2) <- sapply(int2, function(x) paste(x$ID[1],
                                              x$new[1], sep = "_"))

CodePudding user response:

Using group_split will not name the list elements. It is specified in the ?group_split

it does not name the elements of the list based on the grouping as this typically loses information and is confusing.

Instead use split from base R, which will return with the names pasteed using . from the 'ID', 'new' columns

int1 <- df %>%
  # arrange(ID) %>%   # skipped for readability of result
  mutate(new = floor_date(date, '10 day')) %>%
  mutate(new = if_else(day(new) == 31, new - days(10), new)) %>% 
  group_by(ID, new) %>%
  filter(Month == "1") %>% ungroup %>% 
  {split(., .[c('ID', 'new')])}

Similarly for int2

  • Related