Home > Blockchain >  Extracting the data frame name inside a function to create a new column
Extracting the data frame name inside a function to create a new column

Time:04-05

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

CodePudding user response:

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

CodePudding user response:

In base R, use Map/transform

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

CodePudding user response:

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.

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

CodePudding user response:

A one-liner with purrr::imap:

library(tidyverse)

df_FUN <- imap(df_LIST, ~ transmute(.x, df_NAME = .y))
list2env(df_FUN, .GlobalEnv)

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

CodePudding user response:

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

CodePudding user response:

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
  • Related