Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
已知可能的输出时加速'strsplit'_R_Performance_Reshape2_Strsplit_Stringr - Fatal编程技术网

已知可能的输出时加速'strsplit'

已知可能的输出时加速'strsplit',r,performance,reshape2,strsplit,stringr,R,Performance,Reshape2,Strsplit,Stringr,我有一个大数据框,其中有一个factor列,我需要通过分隔符将factor名称拆分为三个factor列。这是我目前的方法,对于大数据帧(有时是几百万行),速度非常慢: 数据这可能会带来相当大的增长: library(data.table) DT <- data.table(data.df) DT[, c("Species", "SizeClass", "Infected") := as.list(strsplit(Class, "\\.")[[1]]), by=Class

我有一个大数据框,其中有一个factor列,我需要通过分隔符将factor名称拆分为三个factor列。这是我目前的方法,对于大数据帧(有时是几百万行),速度非常慢:


数据这可能会带来相当大的增长:

library(data.table)
DT <- data.table(data.df)


DT[, c("Species", "SizeClass", "Infected") 
      := as.list(strsplit(Class, "\\.")[[1]]), by=Class ]

只需使用
gsub
提取所需的字符串部分,而不是将所有内容拆分并尝试将其重新组合在一起,就可以大大提高速度:

data <- readRDS("~/Downloads/data.rds")
data.df <- reshape2:::melt.array(data)

# using `strsplit`
system.time({
cl <- which(names(data.df)=="Class")
Classes <- do.call(rbind, strsplit(as.character(data.df$Class), "\\."))
colnames(Classes) <- c("Species", "SizeClass", "Infected")
data.df <- cbind(data.df[,1:(cl-1)],Classes,data.df[(cl+1):(ncol(data.df))])
})

user  system elapsed 
3.349   0.062   3.411 

#using `gsub`
system.time({
data.df$Class <- as.character(data.df$Class)
data.df$SizeClass <- gsub("(\\w+)\\.(\\d+)\\.(\\w+)", "\\2", data.df$Class,
  perl = TRUE)
data.df$Infected  <- gsub("(\\w+)\\.(\\d+)\\.(\\w+)", "\\3", data.df$Class, 
  perl = TRUE)
data.df$Class  <- gsub("(\\w+)\\.(\\d+)\\.(\\w+)", "\\1", data.df$Class, 
  perl = TRUE)
})

user  system elapsed 
0.812   0.037   0.848 

data看起来你有一个因素,所以在各个层次上工作,然后映射回来。在
strsplit
中使用
fixed=TRUE
,调整为
split=“.”


快的类!尽管您需要将
用作.character(Class)
。可以在同一命令中将列作为因子返回吗?可以转换为因子,但在转换后作为第二行返回。在包含“by”参数的同一调用中使用as.factor必然会减慢进程。@NoamRoss,对
as.character
的捕捉很好。更新的代码加上一些额外的steps@RicardoSaporta我认为您高估了向数据帧添加新列的速度。
f@RicardoSaporta我并不反对data.table更快,但一般来说,创建列不太可能是瓶颈(除非您是以一种天真的方式在循环中进行)事实上,这是一个很好的答案——简单且不添加新的依赖项。但是,对于大数据.frame,连接也可能很慢,因此Ricardo的
data.frame
构造对我来说是一个更好的解决方案。哎呀,这意味着
data.table
构造,但我似乎在这么长时间后无法编辑注释。这个建议将我的代码速度提高了一个数量级!谢谢
# Save the new col names as a character vector 
newCols <- c("Species", "SizeClass", "Infected") 

# split the string, then convert the new cols to columns
DT[, c(newCols) := as.list(strsplit(as.character(Class), "\\.")[[1]]), by=Class ]
DT[, c(newCols) := lapply(.SD, factor), .SDcols=newCols]

# remove the old column. This is instantaneous. 
DT[, Class := NULL]

## Have a look: 
DT[, lapply(.SD, class)]
#       Time Location Replicate Population Species SizeClass Infected
# 1: integer  integer   integer    numeric  factor    factor   factor

DT
data <- readRDS("~/Downloads/data.rds")
data.df <- reshape2:::melt.array(data)

# using `strsplit`
system.time({
cl <- which(names(data.df)=="Class")
Classes <- do.call(rbind, strsplit(as.character(data.df$Class), "\\."))
colnames(Classes) <- c("Species", "SizeClass", "Infected")
data.df <- cbind(data.df[,1:(cl-1)],Classes,data.df[(cl+1):(ncol(data.df))])
})

user  system elapsed 
3.349   0.062   3.411 

#using `gsub`
system.time({
data.df$Class <- as.character(data.df$Class)
data.df$SizeClass <- gsub("(\\w+)\\.(\\d+)\\.(\\w+)", "\\2", data.df$Class,
  perl = TRUE)
data.df$Infected  <- gsub("(\\w+)\\.(\\d+)\\.(\\w+)", "\\3", data.df$Class, 
  perl = TRUE)
data.df$Class  <- gsub("(\\w+)\\.(\\d+)\\.(\\w+)", "\\1", data.df$Class, 
  perl = TRUE)
})

user  system elapsed 
0.812   0.037   0.848 
Classes <- do.call(rbind, strsplit(levels(data.df$Class), ".", fixed=TRUE))
colnames(Classes) <- c("Species", "SizeClass", "Infected")
df0 <- as.data.frame(Classes[data.df$Class,], row.names=NA)
cbind(data.df, df0)