连接行并删除连续的重复项或重复元素
Concatenating rows and dropping the successive repetitions or repeating elements
我有一个数据框如下,我想根据票号连接序列中的行(如果连续重复则删除它们)并确定它们是如何传递给人们的。
ticket<- c("1", "1", "1", "2", "2", "2", "2")
name<- c("Olg", "Jan", "Jan", "Olg", "Jan", "Jan","Olg")
df<- data.frame(ticket, name)
我想创建一个名为序列的变量列,它提供路径并抑制连续重复,如图所示(Olg-Jan-Jan 到 Olg-Jan 和 Olg-Jan-Jan-Olg 到 Olg-Jan-Olg ).有什么建议么?谢谢!
seq<- c("Olg-Jan", "Olg-Jan", ""Olg-Jan", "Olg-Jan-Olg","Olg-Jan-Olg","Olg-Jan-Olg" )
name
是一个因子(如果不是,我们可以将其转换为因子)因此我们使用基础数字因子代码来检查连续的重复项并删除它们。我们使用 dplyr
以便我们可以轻松地按 ticket
分组并使用链接运算符 (%>%
).
将函数链接在一起
library(dplyr)
df %>% group_by(ticket) %>%
filter(c(1, diff(as.numeric(name))) !=0) %>%
summarise(sequence = paste(name, collapse="-"))
ticket sequence
1 1 Olg-Jan
2 2 Olg-Jan-Olg
如果你想保留原始数据框的所有行并只添加序列,那么你可以left_join
将上面的输出left_join
到你的原始数据框:
df = df %>%
left_join(df %>% group_by(ticket) %>%
filter(c(1, diff(as.numeric(name))) !=0) %>%
summarise(sequence = paste(name, collapse="-")))
ticket name sequence
1 1 Olg Olg-Jan
2 1 Jan Olg-Jan
3 1 Jan Olg-Jan
4 2 Olg Olg-Jan-Olg
5 2 Jan Olg-Jan-Olg
6 2 Jan Olg-Jan-Olg
7 2 Olg Olg-Jan-Olg
如果我没理解错的话....
> df_to_list <- split(df, df$ticket)
> df_to_list
$`1`
ticket name
1 1 Olg
2 1 Jan
3 1 Jan
$`2`
ticket name
4 2 Olg
5 2 Jan
6 2 Jan
7 2 Olg
现在我们要循环并取消列出名称,然后删除连续出现相同名称的情况,然后绑定。
new_df <- lapply(df_to_list, function(i){
a <- as.character(unlist(i[['name']]))
endr <- length(a) - 1
b <- sapply(1:endr, function(x){
a[x] != a[x+1]
})
c <- a[b]
paste0(c, collapse = "-")
}) %>% melt %>% select(ticket = L1, seq = value)
> new_df
ticket seq
1 1 Olg-Jan
2 2 Olg-Jan-Olg
这就是你想要的吗?
注意:使用 group_by 方法与这种方法的速度差异产生了有趣的输出时间。我将集合复制到 14000 行并将新数据框命名为 addf
并将两个解决方案包装到单独的函数 using_group
和 `no_group 中。
> system.time(using_group(addf))
user system elapsed
0.012 0.000 0.011
> system.time(no_group(addf))
user system elapsed
0.004 0.000 0.004
我有一个数据框如下,我想根据票号连接序列中的行(如果连续重复则删除它们)并确定它们是如何传递给人们的。
ticket<- c("1", "1", "1", "2", "2", "2", "2")
name<- c("Olg", "Jan", "Jan", "Olg", "Jan", "Jan","Olg")
df<- data.frame(ticket, name)
我想创建一个名为序列的变量列,它提供路径并抑制连续重复,如图所示(Olg-Jan-Jan 到 Olg-Jan 和 Olg-Jan-Jan-Olg 到 Olg-Jan-Olg ).有什么建议么?谢谢!
seq<- c("Olg-Jan", "Olg-Jan", ""Olg-Jan", "Olg-Jan-Olg","Olg-Jan-Olg","Olg-Jan-Olg" )
name
是一个因子(如果不是,我们可以将其转换为因子)因此我们使用基础数字因子代码来检查连续的重复项并删除它们。我们使用 dplyr
以便我们可以轻松地按 ticket
分组并使用链接运算符 (%>%
).
library(dplyr)
df %>% group_by(ticket) %>%
filter(c(1, diff(as.numeric(name))) !=0) %>%
summarise(sequence = paste(name, collapse="-"))
ticket sequence 1 1 Olg-Jan 2 2 Olg-Jan-Olg
如果你想保留原始数据框的所有行并只添加序列,那么你可以left_join
将上面的输出left_join
到你的原始数据框:
df = df %>%
left_join(df %>% group_by(ticket) %>%
filter(c(1, diff(as.numeric(name))) !=0) %>%
summarise(sequence = paste(name, collapse="-")))
ticket name sequence 1 1 Olg Olg-Jan 2 1 Jan Olg-Jan 3 1 Jan Olg-Jan 4 2 Olg Olg-Jan-Olg 5 2 Jan Olg-Jan-Olg 6 2 Jan Olg-Jan-Olg 7 2 Olg Olg-Jan-Olg
如果我没理解错的话....
> df_to_list <- split(df, df$ticket)
> df_to_list
$`1`
ticket name
1 1 Olg
2 1 Jan
3 1 Jan
$`2`
ticket name
4 2 Olg
5 2 Jan
6 2 Jan
7 2 Olg
现在我们要循环并取消列出名称,然后删除连续出现相同名称的情况,然后绑定。
new_df <- lapply(df_to_list, function(i){
a <- as.character(unlist(i[['name']]))
endr <- length(a) - 1
b <- sapply(1:endr, function(x){
a[x] != a[x+1]
})
c <- a[b]
paste0(c, collapse = "-")
}) %>% melt %>% select(ticket = L1, seq = value)
> new_df
ticket seq
1 1 Olg-Jan
2 2 Olg-Jan-Olg
这就是你想要的吗?
注意:使用 group_by 方法与这种方法的速度差异产生了有趣的输出时间。我将集合复制到 14000 行并将新数据框命名为 addf
并将两个解决方案包装到单独的函数 using_group
和 `no_group 中。
> system.time(using_group(addf))
user system elapsed
0.012 0.000 0.011
> system.time(no_group(addf))
user system elapsed
0.004 0.000 0.004