130-R茶话会22-用字典array的特性加速你的代码

2022-05-19 11:33:51 浏览数 (2)

前言

最近有同学后台给我留言。

其大致问题如下:

★统计各个中药,在不同的中药处方出现的频数。 ”

这里就提示我们,中药处方包含的中药数目不同,该为列表结构。

先生成模拟数据:

代码语言:javascript复制
my_list <- vector("list", length = 100)
lapply(1:100, function(x){
  my_index <- sample(1:50, replace = T)
  my_list[[x]] <<- unique(letters[sample(26, size = my_index, replace = T)])
})
my_vector <- unique(unlist(my_list))

因为每个中药处方中的中药只会出现一次,因此unique 一下。

R似乎让我忘记了时间复杂度

最暴力的方式,也就是逐一判断了。

我们首先将my_list 来unlist 一下,得到全部中药的向量。

然后拿每个向量去判断其是否在处方中,对应一个处方长度的逻辑值向量。统计其中的T,即是每个中药的频数。

但是,这个时间复杂度,可是处方总长度x中药长度x每个处方的长度。太慢了,不想写代码。

幸好我练习了字典

在python 中,有专门的字典对象,dict。

在R中,是没有特别的字典结构的。

但其实,列表对象,或者说有名列表,广义来说便是一个字典。

代码语言:javascript复制
my_dict <- lapply(rep(0,length(my_vector)), "[") # 长度为全部中药的计数为0 的列表
names(my_dict) <- my_vector
for (i in my_list){
  for (z in i){
    my_dict[[z]] <- my_dict[[z]]   1
  }
}

直接遍历中药处方中的全部中药即可。

代码语言:javascript复制
tmp <- t(as.data.frame(my_dict))

最后转成数据框即可:

R 有时候还是会让人迟钝啊。

还想加速?foreach?做人不能太贪啊。

0 人点赞