Как использовать purrr :: map family для непосредственного применения функции к списку фреймов данных, а не для создания новых объектов - PullRequest
1 голос
/ 24 марта 2020

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

В качестве примера я иметь два фрейма данных df_a и df_b и функцию age_category, которая добавляет столбец, в котором указывается, является ли человек ребенком или взрослым, в зависимости от его возраста.

df_a <- data.frame(Region = c("North", "South"), Age = c(14, 50))
df_b <- data.frame(Staple = c("Rice", "Potato"), Age = c(35, 2))

df_a
>   Region Age
> 1  North  14
> 2  South  50

df_b
>   Staple Age
> 1   Rice  35
> 2 Potato   2

age_category <- function(x){
  x$category <- ifelse(x$Age >= 18, "adult", "child")
  return(x)
}

I создайте список фреймов данных и примените к ним функцию.

df_list <- list(df_a, df_b)

library(purrr)
exmpl_1 <- purrr::map(df_list, age_category)
exmpl_1

> [[1]]
>   Region Age category
> 1  North  14    child
> 2  South  50    adult

> [[2]]
>   Staple Age category
> 1   Rice  35    adult
> 2 Potato   2    child

Теперь я могу использовать exmpl_1[[1]] для перезаписи df_a (df_a <- exmpl_1[[1]]) и то же самое для df_b.

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

age_category_alt <- function(x){
  x$category <- ifelse(x$Age >= 18, "adult", "child")
  assign(deparse(substitute(x)), x)
}

walk(df_list, age_category_alt)

Но это не работает. Фреймы данных не меняются, и единственным результатом является это предупреждение:

Warning messages:
1: In assign(deparse(substitute(x)), x) :
  only the first element is used as variable name
2: In assign(deparse(substitute(x)), x) :
  only the first element is used as variable name

Я прошу помощи.

1 Ответ

1 голос
/ 24 марта 2020

Есть несколько способов справиться с этим, хотя я лично предпочитаю хранить данные в списках, а не в отдельных фреймах данных.

library(purrr)

1) Используя именованный список и функцию age_category из OP, мы можем использовать map и list2env

df_list <- list(df_a = df_a, df_b = df_b)

df_list <- map(df_list, age_category)
list2env(df_list, .GlobalEnv)

df_a
#  Region Age category
#1  North  14    child
#2  South  50    adult

df_b
#  Staple Age category
#1   Rice  35    adult
#2 Potato   2    child

2) Используя тот же именованный список сверху и assign с imap.

age_category_alt <- function(x, y){
  x$category <- ifelse(x$Age >= 18, "adult", "child")
  assign(y, x, envir = .GlobalEnv)
}

imap(df_list, age_category_alt)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...