R:在同一列上逐行操作以产生N个更多列

时间:2015-07-13 07:55:22

标签: r

我正在尝试根据数据表中的列(路径)提出多个列。我的数据集目前有600万行。

编辑:包含天真的最小数据集

set.seed(24);
DATA <- data.frame(path=paste0(sample(LETTERS[1:3], 25, replace=TRUE),">",sample(LETTERS[1:3], 25, replace=TRUE)), value=rnorm(25))

以下是我目前正在使用的代码(当然我不是在使用字母表):

for (i in 1:nrow(DATA)) {
  if(grepl("A", DATA$path[i])){DATA$A[i]=1}else{DATA$A[i]=0}
  if(grepl("B", DATA$path[i])){DATA$B[i]=1}else{DATA$B[i]=0}
  if(grepl("C", DATA$path[i])){DATA$C[i]=1}else{DATA$C[i]=0}
}

我使用的旧版代码是:

DATA$A <- sapply(DATA$path, function(x) { if(grepl("A", x)){1}else{0}})
DATA$B <- sapply(DATA$path, function(x) { if(grepl("B", x)){1}else{0}})

我要输出的每一列。

但这种效率非常低,因为它太多次了。

我的问题是:是否有更有效的方法来做同样的事情?还是我坚持使用第一个代码块?

提前致谢!

2 个答案:

答案 0 :(得分:2)

我们可以split路径&#39; >列,并获取该列中的unique元素(&#39; Un1&#39;)。循环过来&#39; Un1&#39;并使用grepl查找匹配项。

Un1 <- sort(unique(unlist(strsplit(as.character(DATA$path), '>'))))
DATA[Un1] <- lapply(Un1, function(x) as.integer(grepl(x, DATA$path)))

或另一种选择是在mtabulate输出qdapTools上使用strsplit,否定(!)将0转换为&#39; TRUE&# 39;和所有其他值为“FALSE&#39;”,再次否定,以便&#39; FALSE&#39;成为&#39; TRUE&#39;反之亦然,用+(包装它来强制逻辑到整数。我们也可以使用as.integer+0L等。

library(qdapTools)
cbind(DATA, +(!!mtabulate(strsplit(as.character(DATA$path), '>')) ))

或者在分开“路径”之后我们可以循环列,应用model.matrix并将|Reduce一起使用

 d1 <- do.call(rbind.data.frame,strsplit(as.character(DATA$path), '>'))
 names(d1) <- paste0('path', 1:2)
 cbind(DATA, +(Reduce(`|`,lapply(d1, function(x) model.matrix(~0+x)))))

答案 1 :(得分:1)

为什么不简单:

DATA$A = grepl('A', DATA$path) + 0L