2015-07-13 72 views
1

我想根据数据表中的列(路径)想出多个列。我的数据集目前有6百万行。R:在同一列上进行行操作以生成N个列

编辑:包括最小数据集,则天真

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)) 

下面是我目前使用的代码(当然我不是grepl'ing字母):

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}}) 

为我想要输出的每一列。

但这是非常低效的,因为它提供了太多次。

我的问题是:有没有更有效的方法来做同样的事情?或者我坚持第一个代码块?

提前致谢!

+0

多少列,你必须输入?超过4/5? –

+0

@ColonelBeauvel是的,我需要超过4/5列,可能10或更多,具体取决于路径内容。 – iukie

+0

@akrun我已经添加了基于你的例子的示例数据,我认为这个问题略微澄清。 – iukie

回答

2

我们可以split>的 '路径' 栏,并获得在该列( 'UN1')的unique元素。循环“Un1”并使用grepl找到匹配项。

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

或者另一种选择是在strsplit输出使用mtabulateqdapTools,否定(!),以0转换为“TRUE”和所有其他值“假”,再次否定使“假”变“真'反之亦然,用+(来包装它以强制逻辑为整数。我们也可以使用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

这似乎是我正在寻找!谢谢! – iukie

1

为什么不干脆:

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

这也是可用的,但我正在寻找一个更简洁的解决方案,它不涉及贯穿整个数据集N(我需要创建的列数)次。 – iukie

相关问题