6

I am trying to create a new column with the data frame's name inside a function.

Here is my code:

df1 <- data.frame(var1 = seq(1:10))
df2 <- data.frame(var2 = seq(1:10))
df3 <- data.frame(var3 = seq(1:10))

df_LIST <- tibble::lst(df1, df2, df3)
df_FUN <- lapply(
  df_LIST, 
  function(x)
  {
    mutate(x, 
           df_NAME = deparse(substitute(x))
    ) %>%
      select("df_NAME") %>%
      na.omit()
  }  
)

list2env(df_FUN, .GlobalEnv)

Result:

> df1
   df_NAME
1        x
2        x
3        x
4        x
5        x
6        x
7        x
8        x
9        x
10       x

Expected result:

> df1
   df_NAME
1      df1
2      df1
3      df1
4      df1
5      df1
6      df1
7      df1
8      df1
9      df1
10     df1

6 Answers 6

7

One option would be purrr::imap:

library(dplyr)

df_LIST <- tibble::lst(df1, df2, df3)
df_FUN <- purrr::imap(
  df_LIST,
  function(x, y) {
    mutate(x,
      df_NAME = y
    ) %>%
      select("df_NAME") %>%
      na.omit()
  }
)

df_FUN$df1
#>    df_NAME
#> 1      df1
#> 2      df1
#> 3      df1
#> 4      df1
#> 5      df1
#> 6      df1
#> 7      df1
#> 8      df1
#> 9      df1
#> 10     df1
Sign up to request clarification or add additional context in comments.

Comments

4

A one-liner with purrr::imap:

library(tidyverse)
df_FUN <- imap(df_LIST, ~ transmute(.x, df_NAME = .y))

> df_FUN$df1

   var1 df_NAME
1     1     df1
2     2     df1
3     3     df1
4     4     df1
5     5     df1
6     6     df1
7     7     df1
8     8     df1
9     9     df1
10   10     df1

Comments

3

In base R, use Map/transform

Map(transform, df_LIST, df_NAME = names(df_LIST))

Comments

3

Another option using cbind and mapply:

df_FUN <- mapply(cbind, df_LIST, "df_NAME"=names(df_LIST), SIMPLIFY=F)

list2env(df_FUN, .GlobalEnv)

Output

> df_FUN$df1

   var1 df_NAME
1     1     df1
2     2     df1
3     3     df1
4     4     df1
5     5     df1
6     6     df1
7     7     df1
8     8     df1
9     9     df1
10   10     df1

Comments

3

transform is copied from @akrun's solution I added lapply:

Map(transform,lapply(df_LIST, function(x) {
  names(x)[ grep("var", names(x))] <- "df_NAME"
  x} ), df_NAME = names(df_LIST))
$df1
   df_NAME
1      df1
2      df1
3      df1
4      df1
5      df1
6      df1
7      df1
8      df1
9      df1
10     df1

$df2
   df_NAME
1      df2
2      df2
3      df2
4      df2
5      df2
6      df2
7      df2
8      df2
9      df2
10     df2

$df3
   df_NAME
1      df3
2      df3
3      df3
4      df3
5      df3
6      df3
7      df3
8      df3
9      df3
10     df3

Comments

3

Another lapply solution here. Since you would like to get the name of the df_LIST, you should use names instead of deparse(substitute(x)).

First few lines of dfs are pasted here for demonstration.

library(dplyr)

setNames(
  lapply(1:length(df_LIST), function(x) 
    transmute(df_LIST[[x]], df_NAME = names(df_LIST[x])) %>% 
      na.omit()), 
  names(df_LIST)
  ) %>% 
  list2env(.GlobalEnv)

df1
   df_NAME
1      df1
2      df1
3      df1

df2
   df_NAME
1      df2
2      df2
3      df2

df3
   df_NAME
1      df3
2      df3
3      df3

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.