将行添加到数据框同时添加列名的有效方法

时间:2019-04-04 11:14:15

标签: r

我有一个循环,其中在每次迭代中,我都会生成一个命名的数值向量并将其内容添加到数据帧中。该数据帧的每个向量都有一行,每一列都是一个唯一的字。由于不同的向量可能包含不同的单词,因此,每增加一个新行,就会增加一列,而其他行则为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 :(得分:0)

我们可以使用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
}