根据索引连接/粘贴不同长度的字符串

时间:2016-04-27 10:22:16

标签: r string concatenation aggregate paste

我想知道如何连接字符串以形成不同且不同长度的序列&根据一个条件改变内容。

这是一个数据框示例(我的DF实际上是大约60000行)。

  1. column index:只是一个索引
  2. to_concat:我要连接的字符串项
  3. max_seq:串联条件的一个例子(to_concat只应该连接,如果它是同一序列的一部分 - 我现在已经在序列中指出了字符串的位置。
  4. concat_result:我想要的结果

    index to_concat  max_seq    concat_result
    1        Abc!      1         <abc!+def+_>
    2        def       2         <abc!+def+_>
    3        _         3         <abc!+def+_>
    4        x93       1         <x93+afza+5609+5609+Abc!+def>
    5        afza      2         <x93+afza+5609+5609+Abc!+def>
    6        5609      3         <x93+afza+5609+5609+Abc!+def>
    7        5609      4         <x93+afza+5609+5609+Abc!+def>
    8        Abc!      5         <x93+afza+5609+5609+Abc!+def>
    9        def       6         <x93+afza+5609+5609+Abc!+def>
    10        _         1         <_+x93+afza>
    11        x93       2         <_+x93+afza>
    12        afza      3         <_+x93+afza>
    
  5. 我知道paste&amp; aggregatelength,可能很有用..但不要看到以哪种方式执行此操作,尤其是如何制定粘贴。

    我想我还应该包括一个&#34;第二个&#34;为max_seq做得更好的索引(例如:要在同一序列中连接的所有字符串具有相同的数字,所以这里我们将有3个序列&#34; 1 1 1 2 2 2 2 2 2 3 3 3 &#34;。

    但我不知道这是否是最快/最简单的解决方案,而且我不知道如何粘贴不同的长度......

    你能帮助一位博士学位吗?非常感谢。

    可重复的例子: dput(dat)

    > dput(dat)
    structure(list(V1 = c("index", "1", "2", "3", "4", "5", "6", 
    "7", "8", "9", "10", "11", "12"), V2 = c("to_concat", "Abc!", 
    "def", "_", "x93", "afza", "5609", "5609", "Abc!", "def", "_", 
    "x93", "afza"), V3 = c("max_seq", "1", "2", "3", "1", "2", "3", 
    "4", "5", "6", "1", "2", "3"), V4 = c("concat_result", "<abc!+def+_>", 
    "<abc!+def+_>", "<abc!+def+_>", "<x93+afza+5609+5609+Abc!+def>", 
    "<x93+afza+5609+5609+Abc!+def>", "<x93+afza+5609+5609+Abc!+def>", 
    "<x93+afza+5609+5609+Abc!+def>", "<x93+afza+5609+5609+Abc!+def>", 
    "<x93+afza+5609+5609+Abc!+def>", "<_+x93+afza>", "<_+x93+afza>", 
    "<_+x93+afza>")), .Names = c("V1", "V2", "V3", "V4"), class = "data.frame", row.names = c(NA,
    -13L))
    

1 个答案:

答案 0 :(得分:4)

获得所需结果的几个选项:

1)使用基数R:

mydf$grp <- cumsum(mydf$max_seq < c(1,head(mydf$max_seq, -1))) + 1
mydf$concat_result <- ave(mydf$to_concat, mydf$grp, 
                          FUN = function(x) paste0('<',paste(x,collapse='+'),'>'))

给出:

> mydf
   index to_concat max_seq grp                 concat_result
1      1      Abc!       1   1                  <Abc!+def+_>
2      2       def       2   1                  <Abc!+def+_>
3      3         _       3   1                  <Abc!+def+_>
4      4       x93       1   2 <x93+afza+5609+5609+Abc!+def>
5      5      afza       2   2 <x93+afza+5609+5609+Abc!+def>
6      6      5609       3   2 <x93+afza+5609+5609+Abc!+def>
7      7      5609       4   2 <x93+afza+5609+5609+Abc!+def>
8      8      Abc!       5   2 <x93+afza+5609+5609+Abc!+def>
9      9       def       6   2 <x93+afza+5609+5609+Abc!+def>
10    10         _       1   3                  <_+x93+afza>
11    11       x93       2   3                  <_+x93+afza>
12    12      afza       3   3                  <_+x93+afza>

2)或使用data.table包:

library(data.table)
setDT(mydf)[, grp := cumsum(max_seq < shift(max_seq, fill = 0))+1
            ][, concat_result := paste0('<',paste(to_concat,collapse='+'),'>'), grp][]

3)或使用dplyr包:

library(dplyr)
mydf %>%
  mutate(grp = cumsum(max_seq < lag(max_seq, n=1, default=0))+1) %>%
  group_by(grp) %>%
  mutate(concat_result = paste0('<',paste(to_concat,collapse='+'),'>'))

使用过的数据:

mydf <- structure(list(index = 1:12, 
                       to_concat = c("Abc!", "def", "_", "x93", "afza", "5609", "5609", "Abc!", "def", "_", "x93", "afza"), 
                       max_seq = c(1L, 2L, 3L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L)), 
                  .Names = c("index", "to_concat", "max_seq"), class = "data.frame", row.names = c(NA, -12L))