我有一个data.frame
数据
data = structure(list(mystring = c("AASDAASADDLKJLKADDLKKLLKJLJADDLJLKJLADLKLADD",
"ASDSDFJSKADDKJSJKDFKSADDLKJFLAK"), class = c("cat", "dog")), .Names = c("mystring",
"class"), row.names = c(NA, -2L), class = "data.frame")
看起来像
#> dtt1
# mystring class
#1 AASDAASADDLKJLKADDLKKLLKJLJADDLJLKJLADLKLADD cat
#2 ASDSDFJSKADDKJSJKDFKSADDLKJFLAK dog
我在mystring
下的字符串的前20个字符中搜索“ADD”模式的开头和结尾位置,并将class
视为组。
我正在使用str_locate
stringr
个包来执行此操作。这是我的尝试
setDT(dtt1)[,
cbind(list(str_locate_all(substr(as.character(mystring), 1, 20),"ADD")[[1]][,1]),
list(str_locate_all(substr(as.character(mystring), 1, 20),"ADD")[[1]][,2])),
by = class]
这会提供所需的输出
# class V1 V2
#1: cat 8 10
#2: cat 16 18
#3: dog 10 12
问题:
我想知道这是否是一种标准方法,或者这可以以更有效的方式完成。 str_locate
在不同的列中提供匹配模式的start
和end
位置,并将它们与cbind
一起放在单独的列表中data.table
?另外,如何在此处为cbinded colnames
指定columns
?
答案 0 :(得分:4)
我认为你首先应该减少每组的操作,所以我首先要为所有组创建一个子字符串。
setDT(data)[, submystring := .Internal(substr(mystring, 1L, 20L))]
然后,使用stringi
包(我不喜欢包装),你可以做(虽然目前不能保证效率)
library(stringi)
data[, data.table(matrix(unlist(stri_locate_all_fixed(submystring, "ADD")), ncol = 2)), by = class]
# class V1 V2
# 1: cat 8 10
# 2: cat 16 18
# 3: dog 10 12
或者,您可以避免每组matrix
和data.table
次呼叫,但在检测到所有位置后传播数据
res <- data[, unlist(stri_locate_all_fixed(submystring, "ADD")), by = class]
res[, `:=`(varnames = rep(c("V1", "V2"), each = .N/2), MatchCount = rep(1:(.N/2), .N/2)), by = class]
dcast(res, class + MatchCount ~ varnames, value.var = "V1")
# class MatchCount V1 V2
# 1: cat 1 8 10
# 2: cat 2 16 18
# 3: dog 1 10 12
第三个类似的选项可能是尝试首先在整个数据集上运行stri_locate_all_fixed
,然后再向每个组unlist
运行(而不是同时运行unlist
和stri_locate_all_fixed
每组)
res <- data[, .(stri_locate_all_fixed(submystring, "ADD"), class = class)]
res[, N := lengths(V1)/2L]
res2 <- res[, unlist(V1), by = "class,N"]
res2[, `:=`(varnames = rep(c("V1", "V2"), each = N[1L]), MatchCount = rep(1:(N[1L]), N[1L])), by = class]
dcast(res2, class + MatchCount ~ varnames, value.var = "V1")
# class MatchCount V1 V2
# 1: cat 1 8 10
# 2: cat 2 16 18
# 3: dog 1 10 12
答案 1 :(得分:3)
我们可以将matrix
输出从str_locate_all
更改为data.frame
,并使用rbindlist
创建列。
setDT(data)[,rbindlist(lapply(str_locate_all(substr(mystring, 1, 20),
'ADD'), as.data.frame)) , class]
# class start end
#1: cat 8 10
#2: cat 16 18
#3: dog 10 12
答案 2 :(得分:2)
这是我的表现。
sizeof(int*)/sizeof(int)