R: преобразование нескольких наборов в кадры данных одновременно - PullRequest
0 голосов
/ 07 мая 2019

У меня есть 31 набор данных, соответствующий данным о 31 учителе.Мне нужно выполнить несколько преобразований для всех этих наборов данных.Одним из них является преобразование всех их в кадры данных

 class(alexandre)
[1] "tbl_df"     "tbl"        "data.frame"

Как я уже сказал, у меня есть 31 аналогичный набор данных, и мне нужно преобразовать все в кадры данных.Мой код для этого был

alexandre <- as.data.frame(alexandre)
adrian <- as.data.frame(adrian)
akemi <- as.data.frame(akemi)
arcanjo <- as.data.frame(arcanjo)
ana_barbara <- as.data.frame(ana_barbara)
brigida <- as.data.frame(brigida)
cleiton <- as.data.frame(cleiton)
daniela <- as.data.frame(daniela)
davi <- as.data.frame(davi)
eliezer <- as.data.frame(eliezer)
eduardo <- as.data.frame(eduardo)
eustaquio <- as.data.frame(eustaquio)
gilberto <- as.data.frame(gilberto)
gilmar <- as.data.frame(gilmar)
jorge <- as.data.frame(jorge)
juarez <- as.data.frame(juarez)
junior <- as.data.frame(junior)

... и добавить несколько строк в этот код (31 строк этого).Очевидно, что все эти строки кода занимают слишком много места, и должен быть более быстрый (и более элегантный) способ сделать это.На самом деле, я попробовал это

teachers <- c(alexandre, akemi, adrian, brigida, davi, ...)

cnames <- function(x){
  colnames(x) <- c(1:18)
}

mapply(cnames, teachers)

Тогда я бы сделал всю работу с несколькими строками кода.И этот метод (сформировать вектор, содержащий все наборы данных, затем использовать mapply для вектора) значительно облегчит мою работу, потому что, как я уже сказал, мне нужно выполнить многократное преобразование для всех этих наборов данных.

Этот код делаетне работает, однако.Я получаю следующую ошибку:

 Error in `colnames<-`(`*tmp*`, value = c(1:18)) : 
  attempt to set 'colnames' on an object with less than two dimensions

Это сообщение об ошибке очень непонятно, я нахожу.Я понятия не имею, что нужно сделать, чтобы заставить код работать, и именно поэтому я здесь.Любые другие методы для достижения того, что я пытаюсь сделать, приветствуются.Спасибо.

Ответы [ 2 ]

3 голосов
/ 07 мая 2019

Как прокомментировано и часто обсуждается в тэге R SO, просто используйте список, чтобы поддерживать все ваши отдельные, аналогично структурированные фреймы данных. Это дает вам следующие преимущества:

  1. Простое последовательное выполнение операций для всех элементов с использованием петель или применение семейных вызовов без отдельных назначений имен.

  2. Организует вашу среду и рабочее пространство с поддержкой одного объекта с легкой ссылкой по номеру или имени вместо 31 объекта, заполняющего вашу глобальную среду.

  3. Облегчает миграцию и обработку фрейма данных с помощью rbind, cbind, split, by или других операций.


Чтобы создать список всех текущих фреймов данных в глобальной среде, используйте фильтрацию eapply или mget для объектов фрейма данных. Каждый возвращает именованный список фреймов данных.

teachers_df_list <- Filter(is.data.frame, eapply(.GlobalEnv, identity))

teachers_df_list <- Filter(is.data.frame, mget(x=ls()))

В качестве альтернативы, используйте исходные фреймы данных из файловых источников, используя объекты списка, такие как list.files:

teachers_df_list <- lapply(list.files(...), function(f) read.csv(f, ...))

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

head(teachers_df_list$alexandre)
tail(teachers_df_list$adrian)
summary(teachers_df_list$akemi)
...

Затем выполните необходимые операции с помощью lapply, например, переименование столбцов с функцией правой стороны, setNames. Запустите другие необходимые операции: aggregate или lm.

new_teachers_df_list <- lapply(teachers_df_list, 
                               function(df) setNames(df, paste0("col_", c(1:18)))

new_teachers_agg_list <- lapply(teachers_df_list, 
                                function(df) aggregate(col1 ~ col2, df, sum))

new_teachers_model_list <- lapply(teachers_df_list, 
                                  function(df) summary(lm(col1 ~ col2, df)))

Даже скомпилируйте все кадры данных в одну основную версию, используя do.call + rbind:

# ADD A TEACHER INDICATOR COLUMN
new_teachers_df_list <- Map(function(df, n) transform(df, teacher=n),
                            new_teachers_df_list, names(new_teachers_df_list))

# BUILD SINGLE DF
teachers_df <- do.call(rbind, new_teachers_df_list)

Даже split основная версия возвращается в отдельные группы, если потребуется позже:

# SPLIT BACK TO LIST OF DFs
teachers_df_list <- split(teachers_df, teachers_df$teacher)
1 голос
/ 07 мая 2019

Может быть, вы могли бы использовать список для хранения всех ваших data.frame.Кажется, это работает, но вам нужно найти способ извлечь все data.frame в списке после этого.

df_1 <- data.frame(c(0, 1, 0), c(3, 4, 5))
df_2 <- data.frame(c(0, 1, 0), c(3, 4, 5))

l <- list(df_1, df_2)

lapply(l, function(x){
  colnames(x) <- 1:2
  return(x)
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...