首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R Plyr Plyr似乎真的很慢

R Plyr Plyr似乎真的很慢
EN

Stack Overflow用户
提问于 2015-03-27 10:11:29
回答 2查看 162关注 0票数 2

我以为我有一个非常简单的数据转换,但出于一个我无法理解的原因,它似乎需要一个永恒,这让我怀疑它可能没有做我所希望的。有人能给点线索吗?

第1部分-将源数据转换为单独的列(实际df有260万行).

给予..。

代码语言:javascript
复制
> V1 <- c("E11 2286 1", "ECAT 2286 1", "M11 2286 1", "M12 2286 1", "MCAT 2286 1", "C24 2287 1")
> df <- data.frame(V1)
> df
           V1
1  E11 2286 1
2 ECAT 2286 1
3  M11 2286 1
4  M12 2286 1
5 MCAT 2286 1
6  C24 2287 1

我希望创建两个新列(itemID & topic),并在每个列中填充V1中相应行的子项。

这是我可以用的;

代码语言:javascript
复制
> require(stringr)
> df$itemID <- sapply(1:nrow(df), function(i) str_split(df[i,"V1"]," ")[[1]][[2]] )
> df$topic  <- sapply(1:nrow(df), function(i) str_split(df[i,"V1"]," ")[[1]][[1]] )

但这需要几分钟的时间,似乎应该有一个更有效的方法。因此,首先我尝试使用;

代码语言:javascript
复制
> sapply(1:nrow(df), function(i) {
                                    t <- str_split(df[i,"V1"]," ")
                                    df$itemID <- t[[1]][[2]] 
                                    df$topic  <- t[[1]][[1]] 
                                  })

一个多小时后,什么都没有。所以我放弃了,因为当单独的命令需要不到20分钟的时候,这显然是毫无进展的。

下一个选择是尝试只执行一个任务,但这也失败了。

代码语言:javascript
复制
> require(plyr)
> require(stringr)
> df$itemID <- ddply(df, .(V1), str_split(df$V1," ")[[1]][[2]], .progress="text"  )

Error in get(as.character(FUN), mode = "function", envir = envir) : 
  object '2286' of mode 'function' was not found

因此,对于本任务的第一部分,任何人都可以使用

  • (一)告诉我哪一种方法可能更快(适用还是蹒跚),以及
  • ( ii)使用这种方法提供了如何将列V1拆分为两个所需组件列的解决方案?

第2部分-收集itemID的所有主题以获得积分.我所需要的任务的第二部分是将26m行(现在为3列)并折叠为itemID的每一行,以便将所有主题保存在一个单元格中。

输出结果应该看起来像..。

代码语言:javascript
复制
  itemID    topic
1 2286      E11,ECAT,M11,M12,MCAT
2 2287      C24

有人能提出这样一种简单的方法来将行聚集成单个单元格吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-27 10:38:36

我们可以用几个选择来提高速度。

1.弦I

stringi包中的函数通常更快。我们可以使用stri_extract_all_regex使用适当的regex提取字母数字字符。在这里,我使用的是基于演示的示例的[[:alnum:]]{2,}rbind list元素(do.call(rbind.data.frame,..)),用setNames更改列名,将'data.frame‘转换为'data.table’(setDT),paste 'topic‘元素按'itemID’分组(toString-是paste(., collapse=', ')的包装器)。

代码语言:javascript
复制
library(stringi)
library(data.table)
setDT(setNames(do.call(rbind.data.frame,stri_extract_all_regex(df$V1,
       '[[:alnum:]]{2,}')), c('topic', 'itemID')))[, 
          list(topic=toString(topic)), itemID]
#   itemID                     topic
#1:   2286 E11, ECAT, M11, M12, MCAT
#2:   2287                       C24

2. dplyr/tidyr

我们可以使用extract from tidyr将单个列转换为多个列,方法是指定适当的regex,并将按“itemID”分组的“主题”元素paste

代码语言:javascript
复制
library(dplyr)
library(tidyr)
 extract(df, V1, into= c('topic', 'itemID'), '([^ ]+) ([^ ]+).*', 
                        convert=TRUE) %>% 
           group_by(itemID) %>% 
           summarise(topic=toString(topic))
#  itemID                     topic
#1   2286 E11, ECAT, M11, M12, MCAT
#2   2287                       C24
票数 6
EN

Stack Overflow用户

发布于 2015-03-27 12:32:08

这个怎么样?使用data.table v1.9.5

代码语言:javascript
复制
require(data.table)
cols = c("topic", "itemID", "tmp")
setDT(df)[, c(cols) := tstrsplit(V1, " ", fixed=TRUE, type.convert=TRUE)]
df[, .(topic=paste(topic, collapse=", ")), by=itemID]
#    itemID                     topic
# 1:   2286 E11, ECAT, M11, M12, MCAT
# 2:   2287                       C24

260万行的基准:

代码语言:javascript
复制
N = 2.6e6L
x = paste(rep(letters, length.out=N), sample(1e4, N, TRUE), "1", sep=" ")
dat = data.frame(x, stringsAsFactors=FALSE)
nrow(dat) # 2.6 million

# dplyr+tidyr
system.time({ans1 <- extract(dat, x, into= c('topic', 'itemID'), 
         '([^ ]+) ([^ ]+).*', convert=TRUE) %>% 
          group_by(itemID) %>% 
         summarise(topic=toString(topic))})
#    user  system elapsed 
#  45.643   0.854  46.777 

# data.table
system.time({
    cols = c("topic", "itemID", "tmp")
    setDT(dat)[, c(cols) := tstrsplit(x, " ", fixed=TRUE, type.convert=TRUE)]
    ans2 <- dat[, .(topic=paste(topic, collapse=", ")), by=itemID]
})    
#    user  system elapsed 
#   1.906   0.064   1.981 

identical(as.data.frame(ans1), setDF(ans2[order(itemID)]))
# [1] TRUE

加速比为~24倍

更新:运行data.table应答,然后dplyr应答将导致7s44s的运行时间,从而导致~6.3xE 214的加速。在data.table方法中运行dplyr时,似乎存在一定的缓存效率。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29298117

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档