R 在data.table中拆分和合并字符串
假设我有以下数据:R 在data.table中拆分和合并字符串,r,data.table,R,Data.table,假设我有以下数据: kat = c("a.b.c.d.e.f", "a.c.e.d.f.s", "a.v") 基准R中的期望输出: > splitted = strsplit(kat, "[.]") > kat2 = sapply(splitted, function(x) paste(x[1:min(5, length(x))], collapse = ".")) > kat2 [1] "a.b.c.d.e" "a.c.e.d.f" "a.v" 问题:如何使用data
kat = c("a.b.c.d.e.f", "a.c.e.d.f.s", "a.v")
基准R中的期望输出:
> splitted = strsplit(kat, "[.]")
> kat2 = sapply(splitted, function(x) paste(x[1:min(5, length(x))], collapse = "."))
> kat2
[1] "a.b.c.d.e" "a.c.e.d.f" "a.v"
问题:如何使用data.table(以“可读”的方式):
我知道如何在技术上做到正确:
dat = data.table(kat = kat)
dat[, kat := sapply(strsplit(kat, "[.]"),
function(x) paste(x[1:min(5, length(x))], collapse = "."))]
但我发现它不是真正可读的,特别是如果我为更长的操作使用它
我是否必须为每个操作创建一个函数
kat3 = function(str){
splitted = strsplit(str, "[.]")
sapply(splitted, function(x) paste(x[1:min(5, length(x))], collapse = "."))
}
dat[, kat := kat3(kat)][]
或者可以在data.table的索引中执行此操作吗
dat[, kat := function(kat){
splitted = strsplit(kat, "[.]")[[1]]
paste(splitted[1:min(5, length(splitted))], collapse = ".")
}, ]
最后一次尝试失败,因为需要将向量返回给kat
sapply
或Vectorize
可以帮助实现这一点
“[.data.table”(dat,`:=`(kat2,函数(kat){:赋值的RHS不是空的,不是原子向量(请参见?is.atomic)也不是列表列)。
smt[1]“a.b.c.d.e”
#使用矢量化或sapply
smt_v a.b.c.d.e.f a.c.e.d.f.s a.v
#>“a.b.c.d.e”“a.c.e.d.f”“a.v”
Sappy(kat、smt)
#>a.b.c.d.e.f a.c.e.d.f.s a.v
#>“a.b.c.d.e”“a.c.e.d.f”“a.v”
如果要对许多变量执行此操作,则可以循环使用它们或使用lappy和.SDcols参数。如果有许多转换,则编写
函数.R
脚本并进行寻源,这可能是进一步研究的最佳方法。:)您上次尝试失败,因为您需要将向量返回给kat。sapply
或Vectorize
可以提供帮助
“[.data.table”(dat,`:=`(kat2,函数(kat){:赋值的RHS不是空的,不是原子向量(请参见?is.atomic)也不是列表列)。
smt[1]“a.b.c.d.e”
#使用矢量化或sapply
smt_v a.b.c.d.e.f a.c.e.d.f.s a.v
#>“a.b.c.d.e”“a.c.e.d.f”“a.v”
Sappy(kat、smt)
#>a.b.c.d.e.f a.c.e.d.f.s a.v
#>“a.b.c.d.e”“a.c.e.d.f”“a.v”
如果要对许多变量执行此操作,则可以循环使用它们或使用lappy和.SDcols参数。如果有许多转换,则编写
函数.R
脚本并进行寻源,这可能是进一步研究的最佳方法。:)使用正则表达式解决问题的另一种方法,在正则表达式中,我们提取单词直到出现第n个字符(此处为点)。这避免了字符串的拆分和连接步骤
从和@Nathan Werth获取正则表达式帮助
library(data.table)
dat[, kat1 := stringr::str_extract(kat, "^(([^\\.]*\\.){0,4}[^\\.]*)")]
dat
# kat kat1
#1: a.b.c.d.e.f a.b.c.d.e
#2: a.c.e.d.f.s a.c.e.d.f
#3: a.v a.v
另一种解决问题的方法是使用正则表达式,我们提取单词直到出现第n个字符(这里是一个点)。这避免了字符串的拆分和连接步骤 从和@Nathan Werth获取正则表达式帮助
library(data.table)
dat[, kat1 := stringr::str_extract(kat, "^(([^\\.]*\\.){0,4}[^\\.]*)")]
dat
# kat kat1
#1: a.b.c.d.e.f a.b.c.d.e
#2: a.c.e.d.f.s a.c.e.d.f
#3: a.v a.v
对于您发布的数据,您可以使用data.table中的
substr(kat,1,10)
或dat[,kat:=substr(kat,1,10)]
获得相同的结果。实际上substr(kat,1,9)
:)sapply
可以用于交互式会话,但不要将其用于编程。使用vapply
对您知道输出的维度和类型的事实进行编码。@Ronaksha您可以给出匹配数的范围,因此您的解决方案只需进行一个小的编辑:stringr::stru extract(kat,“^([^\.]*\){0,4}[^\.]*”)
@NathanWerth ohh..是的。谢谢。我不确定我是否应该将其作为答案发布。对于您发布的数据,您将使用substr(kat,1,10)
或dat[,kat:=substr(kat,1,10)]
在data.table中获得相同的结果。实际上substr(kat,1,9)
:)sapply
可以用于交互式会话,但不要将其用于编程。使用vapply
对您知道输出的维度和类型的事实进行编码。@Ronaksha您可以给出匹配数的范围,因此您的解决方案只需进行一个小的编辑:stringr::stru extract(kat,“^([^\.]*\){0,4}[^\.]*”)
@NathanWerth ohh..是的,谢谢。但我不确定是否应该将其作为答案发布。