如何有条件地将不同的行合并/复制为一行[R]



我有一个大的数据帧,其中包含名称和一个"分类";名为序列的变量序列告诉关于其他行的位置。它有两个值:第一个附加。问题是这些值的分布不均匀,即每个第一个都没有额外的,并且每个letters值都是唯一的。数据帧如下(简化版(:

letters <- sample(LETTERS, 20)
sequence <- c("first","additional","first","first","first","first","first","additional","additional","additional","first","first","additional","first","additional","additional","first","additional","first","first")
df <- data.drame(sequence, letters)

现在,我要做的是获取字母中的每个附加值,并将其粘贴到中相应的第一个数值中。因此,例如,字母列中的第二个(行(值将粘贴到第一个,因为它是相应的附加。此外,字母中的第八个、第九个和第十个值应粘贴在字符的第七个值内(旁边((例如,第一个附加额外其他(。

我尝试了以下操作,但有一个明显的限制,即它只关注下一个值,

library(dplyr)    
df <- df %>% mutate(letters_ok = if_else(sequence == "additional",
paste(letters, lag(letters), sep = "; "), letters))

突出我的问题:我如何在序列中的值上有条件地滞后,以便根据第一个附加分类粘贴字母的值?

由于每个字母值都是唯一的,并且它与特定的序列的值绑定,所以我没有使用group_by。每一个其他的解决方案都是我目前对字符串/字符争论的了解,所以我非常感谢任何帮助。

这里有一个data.table方法。。我稍微修改了一下您的示例数据,因为letters不是一个非常方便的列名。此外,添加set.seed(123)用于复制目的。

样本数据

set.seed(123)
letter <- sample(LETTERS, 20)
sequence <- c("first","additional","first","first","first","first","first","additional","additional","additional","first","first","additional","first","additional","additional","first","additional","first","first")
df <- data.frame(sequence, letter)
#      sequence letter
# 1       first      O
# 2  additional      S
# 3       first      N
# 4       first      C
# 5       first      J
# 6       first      R
# 7       first      K
# 8  additional      E
# 9  additional      X
# 10 additional      Y
# 11      first      W
# 12      first      T
# 13 additional      I
# 14      first      L
# 15 additional      U
# 16 additional      M
# 17      first      P
# 18 additional      H
# 19      first      B
# 20      first      G

代码

library( data.table )
#convert to data.table format
setDT(df)
#add id-column
df[, id := .I ]
#perform rolling join
temp <- df[ sequence == "first", ][ df[ sequence == "additional", ], 
.( x.letter, i.letter, i.id, x.id), 
on = .(id), 
roll = Inf ]
#summarise
temp <- temp[, paste0( `i.letter`, collapse = ";" ), by = .(x.id) ]
#join, drop id column
df[sequence == "first", ][ temp, letter := paste( letter, i.V1, sep = ";"), on = .(id = `x.id`) ][, id := NULL]

输出

#    sequence  letter
# 1:    first     O;S
# 2:    first       N
# 3:    first       C
# 4:    first       J
# 5:    first       R
# 6:    first K;E;X;Y
# 7:    first       W
# 8:    first     T;I
# 9:    first   L;U;M
#10:    first     P;H
#11:    first       B
#12:    first       G

最新更新