Create new variable in dataframe list based on number of columns

Viewed 87

I have a list with two dataframes, the first of which has two columns and the second of which has three.

dat.list<-list(dat1=data.frame(col1=c(1,2,3),
                     col2=c(10,20,30)),
     dat2= data.frame(col1=c(5,6,7),
                      col2=c(30,40,50),
                      col3=c(7,8,9)))

# $dat1
 #  col1 col2
# 1    1   10
# 2    2   20
# 3    3   30

# $dat2
 
#   col1 col2 col3
# 1    5   30    7  
# 2    6   40    8  
# 3    7   50    9 

I am trying to create a new column in both dataframes using map(), mutate() and case_when(). I want this new column to be identical to col3 if the dataframe has more than two columns, and identical to col1 if it has two or less columns. I have tried to do this with the following code:

library(tidyverse)
dat.list %>% map(~ .x %>%
                   mutate(newcol=case_when(ncol(.)>2 ~ col3,
                                           TRUE  ~ col1),
                          ))

However, this returns the following error: "object 'col3' not found". How can I get the desired output? Below is the exact output I am trying to achieve.

# $dat1
#   col1 col2 newcol
# 1    1   10      1
# 2    2   20      2
# 3    3   30      3

# $dat2
#   col1 col2 col3 newcol
# 1    5   30    7      7
# 2    6   40    8      8
# 3    7   50    9      9
1 Answers

if/else will do :

library(dplyr)
library(purrr)

dat.list %>% map(~ .x %>% mutate(newcol= if(ncol(.) > 2) col3 else col1))

#$dat1
#  col1 col2 newcol
#1    1   10      1
#2    2   20      2
#3    3   30      3

#$dat2
#  col1 col2 col3 newcol
#1    5   30    7      7
#2    6   40    8      8
#3    7   50    9      9

Base R using lapply :

lapply(dat.list, function(x) transform(x, newcol = if(ncol(x) > 2) col3 else col1))
Related