我在R中有一个数据表,其中包含冒号分隔数据的文本列。我想返回结果的矩阵/数据表,其中为每个单元格返回一个分隔值。
下面粘贴的代码演示了问题,是一个有效的解决方案。但是,我的实际数据表很大(几千行和几列),粘贴的方法大约需要一两分钟才能完成。
我想知道是否有更有效的方法来执行此任务?看来,sep2
中的fread
选项在实施后对此问题非常有用。
谢谢!
> # 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"
答案 0 :(得分:4)
1)sub 试试这个:
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)或使用data.table中的fread
:
replace(m, TRUE, fread(paste(m, collapse = "\n"))$V2)