使用R中的Data.Table进行滚动文本串联

7

我有一个数据集,长这样:

rownum<-c(1,2,3,4,5,6,7,8,9,10)
name<-c("jeff","jeff","mary","jeff","jeff","jeff","mary","mary","mary","mary")
text<-c("a","b","c","d","e","f","g","h","i","j")
a<-data.table(rownum,name,text)

我想添加一列新的文本,该列通过行号和名称从上一列中添加。新列的向量将是:

rolltext<-c("a","ab","c","abd","abde","abdef","cg","cgh","cghi","cghij"

在这里我不知道该怎么做。对于数字,我只需要使用cumsum函数,但对于文本,我认为我需要使用for循环或其中一个apply函数?

2个回答

8
您可以使用Reduceaccumulate选项来进行操作:
a[, rolltext := Reduce(paste0, text, accumulate = TRUE), by = name]

    rownum name text rolltext
 1:      1 jeff    a        a
 2:      2 jeff    b       ab
 3:      3 mary    c        c
 4:      4 jeff    d      abd
 5:      5 jeff    e     abde
 6:      6 jeff    f    abdef
 7:      7 mary    g       cg
 8:      8 mary    h      cgh
 9:      9 mary    i     cghi
10:     10 mary    j    cghij

另外,可以按照@DavidArenburg的建议,使用sapply来构建每一行:

a[, rolltext := sapply(1:.N, function(x) paste(text[1:x], collapse = '')), by = name]

这是一个累加的总和,而滚动总和(在操作员的标题中)则是另一回事,至少在R语言中是如此。


1
不错。也许还可以 a[, rolltext := sapply(1:.N, function(x) paste(text[1:x], collapse = '')), by = name] - David Arenburg
谢谢,David,我已经编辑好了。缺点可能是需要更多的粘贴(sum(seq(.N)-1)与使用Reduce.N-1相比)。这是我的直觉/猜测。 - Frank

7

这里有一个使用 substring() 的想法。

a[, rolltext := substring(paste(text, collapse = ""), 1, 1:.N), by = name]

这提供了

    rownum name text rolltext
 1:      1 jeff    a        a
 2:      2 jeff    b       ab
 3:      3 mary    c        c
 4:      4 jeff    d      abd
 5:      5 jeff    e     abde
 6:      6 jeff    f    abdef
 7:      7 mary    g       cg
 8:      8 mary    h      cgh
 9:      9 mary    i     cghi
10:     10 mary    j    cghij

我们可能可以通过使用 stringi 包来加快速度。

library(stringi)
a[, rolltext := stri_sub(stri_c(text, collapse = ""), length = 1:.N), by = name]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接