我有一个循环,其中在每次迭代中,我都会生成一个命名的数值向量并将其内容添加到数据帧中。该数据帧的每个向量都有一行,每一列都是一个唯一的字。由于不同的向量可能包含不同的单词,因此,每增加一个新行,就会增加一列,而其他行则为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
我对如何改进这一点迷失了。您是否有一种方法可以更快地运行,同时仍然能够添加列?非常感谢您的帮助!
答案 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)
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
}