Эффективный способ добавления строк в фрейм данных с возможностью добавления имен столбцов - PullRequest
0 голосов
/ 04 апреля 2019

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

Однако, это очень медленный процесс, так как размер данных увеличивается, я думаю, потому чтофрейм данных копируется каждый раз, когда добавляется новая строка.Поэтому мой нынешний подход невозможен для развертывания в большом наборе данных (на моем ноутбуке ~ 650 строк из нескольких тысяч уникальных слов уже занимает часы)

Я нашел некоторые предлагаемые решения, такие как предварительное распределение памяти, ноэто не вариант для меня, так как я не знаю количество уникальных слов (столбцов) заранее.Кроме того, использование data.table должно быть более быстрым, но тогда проверка столбца затруднена, и мне нужен фрейм данных для последующего использования.

Это мой подход прямо сейчас:

# example vectors
named_num1 = c(alpha = 1, beta = 4, gamma =2) 
named_num2 = c(alpha = 5, pi = 2, gamma = 18) 
named_num3 = c(beta = 10, omega = 12, alpha = 2)
list_of_nums = list(named_num1,named_num2,named_num3)

df = data.frame()

# add vectors to dataframe
for (num in list_of_nums){
  temp_df = data.frame(as.list(num))
  df = dplyr::bind_rows(df, temp_df)
}

df[is.na(df)] = 0

Я отчасти заблудился от того, как улучшить это.У вас есть подход, который работает быстрее, но при этом вы можете добавлять столбцы?Большое спасибо за любую помощь!

1 Ответ

0 голосов
/ 04 апреля 2019

Мы можем использовать устаревшие rbind_list от dplyr

rbind_list(list_of_nums)
# A tibble: 3 x 5
#  alpha  beta gamma    pi omega
#  <dbl> <dbl> <dbl> <dbl> <dbl>
#1     1     4     2    NA    NA
#2     5    NA    18     2    NA
#3     2    10    NA    NA    12
#warning:
#'rbind_list' is deprecated.
#Use 'bind_rows()' instead.
#See help("Deprecated") 

тест

l <- rep(list_of_nums, 10000)

library(microbenchmark)
b <- microbenchmark(
  markus = rbind_list(l),
  OP = OP(l), 
  Julian_Hn = bind_rows(!!!l),
  times = 10L
)

autoplot(b)

enter image description here

b
#Unit: milliseconds
#      expr         min          lq        mean      median          uq         max neval cld
#    markus   108.43026   108.98696   119.86560   122.87064   128.76507   134.64753    10  a 
#        OP 33415.89685 33647.62856 34314.40213 34058.06817 34695.69121 36231.96304    10   b
# Julian_Hn    27.36839    27.77864    30.83439    28.44502    29.68894    42.87212    10  a 

Где OP задается

OP <- function(x) {
  df = data.frame()

  for (num in x) {
    temp_df = data.frame(as.list(num))
    df = dplyr::bind_rows(df, temp_df)
  }
  df
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...