Присвоение имени фрейма данных всем строкам в столбце - PullRequest
0 голосов
/ 06 мая 2018

Я хочу добавить имя фрейма данных во все строки столбца, для каждого фрейма данных в списке.

Фиктивные данные:

test_df <- data.frame(x = 1:5, y = c("a","b","c","d","e"))

Что я хочу закончить, так это:

x    y    ref
1    a    test_df
2    b    test_df
3    c    test_df
4    d    test_df
5    e    test_df

Причина в том, что я собираюсь позже связать несколько фреймов данных, и я хочу иметь возможность фильтровать, из какого фрейма данных получены значения. Я попробовал следующее:

library(dplyr)

test <- function(df) {
  df <- df %>%
    mutate(ref = deparse(substitute(df)))
  return(df)
}

Но это только создает столбец с именем ref со значением "df" в каждой строке. Любые предложения с dplyr очень ценятся. Или, может быть, есть способ напрямую создать этот столбец в вызове rbind?

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

Причина в том, что я собираюсь связать несколько фреймов данных позже, и Я хочу иметь возможность фильтровать, из какого фрейма данных получены значения.

Тогда просто используйте dplyr::bind_rows с параметром .id:

library(dplyr)
bind_rows(df_list,.id="name")
# works also : purrr::map_dfr(df_list,identity,.id="name")
# works also : data.table::rbindlist(df_list,idcol="name")

#   name x y
# 1    A 1 a
# 2    A 2 b
# 3    B 1 a
# 4    B 2 b
# 5    C 1 a
# 6    C 2 b

Если вашего data.frames еще нет в списке, обратите внимание, что tibble::lst будет называть элементы при добавлении их в список, например, lst(df_A,df_B,df_C)

Таким образом, ваш пример решается с помощью bind_rows(lst(test_df),.id="name")

Данные

test_df <- data.frame(x = 1:2, y = c("a","b"))
df_list <- setNames(replicate(3,test_df,FALSE),LETTERS[1:3])
# $A
# x y
# 1 1 a
# 2 2 b
# 
# $B
# x y
# 1 1 a
# 2 2 b
# 
# $C
# x y
# 1 1 a
# 2 2 b
0 голосов
/ 06 мая 2018

Используя dplyr, попробуйте это:

library(lazyeval)
test <- function(df) {
   df <- df %>% mutate(ref = expr_label(df))
   return(df)
 }
test(test_df)
  x y       ref
1 a `test_df`
2 b `test_df`
3 c `test_df`
4 d `test_df`
5 e `test_df`

Кроме того, это также работает, но не использует dplyr:

test2 <- function(df) {
  df$ref <- deparse(substitute(df))
  return(df)
}
test2(test_df)
  x y     ref
1 1 a test_df
2 2 b test_df
3 3 c test_df
4 4 d test_df
5 5 e test_df

Сделать эту работу со списками фреймов данных и lapply сложнее из-за того, как работает lapply, но работает следующий обходной путь:

test_df <- data.frame(x = 1:5, y = c("a","b","c","d","e"))
test_df2 <- data.frame(x = 11:15, y = c("aa","bb","cc","dd","ee"))

Здесь я создаю именованный список фреймов данных:

dfs <- setNames(list(test_df, test_df2), c("test_df", "test_df2"))
dfs
$test_df
  x y
1 1 a
2 2 b
3 3 c
4 4 d
5 5 e

$test_df2
   x  y
1 11 aa
2 12 bb
3 13 cc
4 14 dd
5 15 ee

Теперь я изменяю вспомогательную функцию, чтобы она принимала имя в качестве аргумента:

test3 <- function(df, nm) {
  df$ref <- nm
  return(df)
}

Здесь я передаю только имена lapply и извлекаю каждый фрейм данных из именованного списка dfs, который я определил выше.

lapply(names(dfs), function(x) test3(dfs[[x]], x))
[[1]]
  x y     ref
1 1 a test_df
2 2 b test_df
3 3 c test_df
4 4 d test_df
5 5 e test_df

[[2]]
   x  y      ref
1 11 aa test_df2
2 12 bb test_df2
3 13 cc test_df2
4 14 dd test_df2
5 15 ee test_df2

Это не самый элегантный способ, но он работает.

Сказав, что, если вы хотите объединить кадры данных в один отдельный кадр данных, нечего добавить к предложению @ markus использовать bind_rows, как в

bind_rows(dfs, .id="ref")
        ref  x  y
1   test_df  1  a
2   test_df  2  b
3   test_df  3  c
4   test_df  4  d
5   test_df  5  e
6  test_df2 11 aa
7  test_df2 12 bb
8  test_df2 13 cc
9  test_df2 14 dd
10 test_df2 15 ee
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...