2017-06-01 52 views
2

我有一个R中的数据表,其中带有冒号分隔数据的文本列。我想返回一个矩阵/数据表,其中每个单元返回一个分隔值。如何从R中的数据表中有效提取分隔字符串

下面粘贴的代码演示了这个问题并且是一个可行的解决方案。但是,我的实际数据表很大(几千行和几列),粘贴的方法需要一两分钟的时间才能完成。

我想知道是否有更高效的方法来执行此任务?看来fread中的sep2选项对于这个问题一旦实施将非常有用。

谢谢!

> # Set up data.table 
> DT <- data.table(A = c("cat:1:meow", "dog:2:bark", "cow:3:moo"), 
        B = c("dog:3:meow", "dog:4:bark", "frog:3:croak"), 
        C = c("dingo:0:moo", "cat:8:croak", "frog:1:moo")) 
> print(DT) 

     A   B   C 
1: cat:1:meow dog:3:meow dingo:0:moo 
2: dog:2:bark dog:4:bark cat:8:croak 
3: cow:3:moo frog:3:croak frog:1:moo 

# grab the second delimited value in each cell 
> part_index <- 2 
> f = function(x) {vapply(t(x), function(x) {unlist(strsplit(x, ":", fixed=T))[part_index]}, character(1))} 

> sapply(DT, f) 

    A B C 
[1,] "1" "3" "0" 
[2,] "2" "4" "8" 
[3,] "3" "3" "1" 

回答

4

1)子尝试这种情况:

DT[, lapply(.SD, sub, pattern = ".*:(.*):.*", replacement = "\\1")] 

,并提供:

A B C 
1: 1 3 0 
2: 2 4 8 
3: 3 3 1 

2)的fread或使用fread

DT[, lapply(.SD, function(x) fread(paste(x, collapse = "\n"))$V2)] 

3)矩阵注意,类似的代码将与普通的汉字字模工作,没有data.table:

m <- as.matrix(DT) 

replace(m, TRUE, sub(".*:(.*):.*", "\\1", m)) 

捐赠:

 A B C 
[1,] "1" "3" "0" 
[2,] "2" "4" "8" 
[3,] "3" "3" "1" 

3A)更简单(没有正则表达式)将是:

replace(m, TRUE, read.table(text = m, sep = ":")$V2) 

3b)或使用fread from data.table:

replace(m, TRUE, fread(paste(m, collapse = "\n"))$V2) 
相关问题