0

I have a dataset that is wide for 10 sessions and each session has ID#s for two team members. I want to paste the to ID#s together to form team IDs. I can do this with 10 mutate (one for each team), but am trying to find a way to have 1 mutate inside a map or pmap.

A simple data example with only 2 sessions is

df2 <- data.frame( subj = c(1001,1002),
               id1.s1 = c(21, 44), 
               id2.s1 = c(21, 55), 
               id1.s2 = c(23, 44), 
               id2.s2 = c(21, 77))

df2 <- df2 %>%
  mutate(team.s1=paste(id1.s1, id2.s1, sep="-")) %>%
  mutate(team.s2=paste(id1.s2, id2.s2, sep="-")) %>%
  select(grep("subj|team", names(.)))

This gives

  subj team.s1 team.s2
1 1001   21-21   23-21
2 1002   44-55   44-77

Is there a way to make a 3 element list with e1 = 10 team names, e2 = 10 ID#1, e3 = 10 ID#2 and use mutate inside of pmap? OR some other wat that avoids 10 mutate lines?

I could not figure out how to get the data frame name into mutate

D. Bontempo
  • 176
  • 1
  • 1
  • 9

2 Answers2

3

A solution based on 's gather and spread functions. The separate function is to separate one column based on a pattern.

library(dplyr)
library(tidyr)

df2 <- df1 %>%
  gather(ID_S, Value, -subj) %>%
  separate(ID_S, into = c("ID", "S")) %>%
  group_by(subj, S) %>%
  summarise(Value = paste(Value, collapse = "-")) %>%
  mutate(S = paste0("team.", S)) %>%
  spread(S, Value) %>%
  ungroup()
df2
# # A tibble: 2 x 3
# subj team.s1 team.s2
# * <dbl> <chr>   <chr>  
# 1  1001 21-21   23-21  
# 2  1002 44-55   44-77

DATA

df1 <- data.frame( subj = c(1001,1002),
                   id1.s1 = c(21, 44), 
                   id2.s1 = c(21, 55), 
                   id1.s2 = c(23, 44), 
                   id2.s2 = c(21, 77))
www
  • 38,575
  • 12
  • 48
  • 84
1

One option could be split the data frame based on the column names' suffix, i.e., s1/s2 or sessions, then for each session paste the columns with do.call(paste, ...):

With tidyverse (version 1.2.1):

df2 %>% 
    split.default(sub('id[12]\\.(s[0-9]+)', '\\1', names(.))) %>% 
    map_dfc(~do.call(paste, c(sep="-", .)))

# A tibble: 2 x 3
#  s1    s2    subj 
#  <chr> <chr> <chr>
#1 21-21 23-21 1001 
#2 44-55 44-77 1002 
Psidom
  • 209,562
  • 33
  • 339
  • 356