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..是的,谢谢。但我不确定是否应该将其作为答案发布。