标记 Parent ID 然后与 Dataframe 合并
Labeling Parent ID then Merging Back with Dataframe
我正在尝试使用其上方行的 ID(它们的 parent ID)来标记行。在下面的例子中,我对你会对一个人说的不同事情感到不满。它们分为问候、告别、问题等。假设每个 classification/group 的第一个条目是根,我试图用根的 ID 标记第一个 child (第二个条目) .
下面的代码能够标记第二个 child,但是,由于过滤器,我最终得到的小标题缺少两个条目。过滤器很重要,因为实际上数据集更复杂,所以它(很可能)需要保留。
我怎样才能将新标记的小标题与原来的小标题合并回来?另外,如果有办法在管道链中执行此操作,那就更好了。
library(dplyr)
test_df <- tibble(msg_id = as.character(c(1, 2, 3, 4, 5, 6, 7, 8)),
msg_group = c("greeting", "greeting", "greeting", "greeting",
"farewell", "farewell", "question", "question"),
content = c("hello", "hey there", "morning", "howdy", "bye",
"see ya", "how are you", "who are you"),
parent_id = NA_character_)
labeling_test <- test_df %>%
group_by(msg_group) %>%
mutate(rank = rank(msg_id)) %>%
filter(rank <= 2)
#sorts these into ranks within each group
#rank 1 is the root, rank 2 will be the first child of root
for(i in seq(1, nrow(labeling_test), 2)){
labeling_test[i + 1,]$parent_id <- labeling_test[i,]$msg_id
}
#label the even number items with id of the item before it
#in terms of this code, label rank 2 with the id of rank 1,
#rank 4 with the id of rank 3...
labeling_test
最终目标将是一个如下所示的数据框:
# A tibble: 8 x 6
msg_id msg_group content parent_id rank
<chr> <chr> <chr> <chr> <dbl>
1 1 greeting hello NA 1
2 2 greeting hey there 1 2
3 3 greeting morning NA 3
4 4 greeting howdy NA 4
5 5 farewell bye NA 1
6 6 farewell see ya 5 2
7 7 question how are you NA 1
8 8 questions who are you 7 1
最终目标实际上是将电子邮件线程变成树结构。标记前两封电子邮件很容易,因为它们是最早的和第二旧的。之后它变得更加复杂。 gmail 线程的棘手部分是它们不存储 parent 消息(或者我还没有找到它的存储位置)。所以你必须使用消息的内容来标记parents。此外,使用电子邮件的时间戳也不起作用,因为人们可以单独回复消息并开始新的分支,而时间与他们在分支中的位置无关。
并不是说这对上面的问题很重要。如果您知道有关此主题的一些信息,那也很棒。
我认为 join/merge 操作是最有效的:
test_df %>%
group_by(msg_group) %>%
mutate(rank = rank(group_id)) %>%
filter(rank <= 2) %>%
ungroup() %>%
select(msg_id, rank) %>%
left_join(test_df, ., by = "msg_id")
# # A tibble: 8 x 6
# group_id msg_id msg_group content parent_id rank
# <dbl> <chr> <chr> <chr> <chr> <dbl>
# 1 1 1 greeting hello <NA> 1
# 2 2 2 greeting hey there <NA> 2
# 3 3 3 greeting morning <NA> NA
# 4 4 4 greeting howdy <NA> NA
# 5 1 5 farewell bye <NA> 1
# 6 2 6 farewell see ya <NA> 2
# 7 1 7 question how are you <NA> 1
# 8 2 8 questions who are you <NA> 1
编辑:也许你不需要join/merge,只需用
就地改变
test_df %>%
group_by(msg_group) %>%
mutate(parent_id = if_else(row_number() == 2, msg_id[1], NA_character_))
# # A tibble: 8 x 4
# # Groups: msg_group [3]
# msg_id msg_group content parent_id
# <chr> <chr> <chr> <chr>
# 1 1 greeting hello <NA>
# 2 2 greeting hey there 1
# 3 3 greeting morning <NA>
# 4 4 greeting howdy <NA>
# 5 5 farewell bye <NA>
# 6 6 farewell see ya 5
# 7 7 question how are you <NA>
# 8 8 question who are you 7
(我认为没有必要为 这个 目的创建 rank
列,但这没有坏处。)
我正在尝试使用其上方行的 ID(它们的 parent ID)来标记行。在下面的例子中,我对你会对一个人说的不同事情感到不满。它们分为问候、告别、问题等。假设每个 classification/group 的第一个条目是根,我试图用根的 ID 标记第一个 child (第二个条目) .
下面的代码能够标记第二个 child,但是,由于过滤器,我最终得到的小标题缺少两个条目。过滤器很重要,因为实际上数据集更复杂,所以它(很可能)需要保留。
我怎样才能将新标记的小标题与原来的小标题合并回来?另外,如果有办法在管道链中执行此操作,那就更好了。
library(dplyr)
test_df <- tibble(msg_id = as.character(c(1, 2, 3, 4, 5, 6, 7, 8)),
msg_group = c("greeting", "greeting", "greeting", "greeting",
"farewell", "farewell", "question", "question"),
content = c("hello", "hey there", "morning", "howdy", "bye",
"see ya", "how are you", "who are you"),
parent_id = NA_character_)
labeling_test <- test_df %>%
group_by(msg_group) %>%
mutate(rank = rank(msg_id)) %>%
filter(rank <= 2)
#sorts these into ranks within each group
#rank 1 is the root, rank 2 will be the first child of root
for(i in seq(1, nrow(labeling_test), 2)){
labeling_test[i + 1,]$parent_id <- labeling_test[i,]$msg_id
}
#label the even number items with id of the item before it
#in terms of this code, label rank 2 with the id of rank 1,
#rank 4 with the id of rank 3...
labeling_test
最终目标将是一个如下所示的数据框:
# A tibble: 8 x 6
msg_id msg_group content parent_id rank
<chr> <chr> <chr> <chr> <dbl>
1 1 greeting hello NA 1
2 2 greeting hey there 1 2
3 3 greeting morning NA 3
4 4 greeting howdy NA 4
5 5 farewell bye NA 1
6 6 farewell see ya 5 2
7 7 question how are you NA 1
8 8 questions who are you 7 1
最终目标实际上是将电子邮件线程变成树结构。标记前两封电子邮件很容易,因为它们是最早的和第二旧的。之后它变得更加复杂。 gmail 线程的棘手部分是它们不存储 parent 消息(或者我还没有找到它的存储位置)。所以你必须使用消息的内容来标记parents。此外,使用电子邮件的时间戳也不起作用,因为人们可以单独回复消息并开始新的分支,而时间与他们在分支中的位置无关。
并不是说这对上面的问题很重要。如果您知道有关此主题的一些信息,那也很棒。
我认为 join/merge 操作是最有效的:
test_df %>%
group_by(msg_group) %>%
mutate(rank = rank(group_id)) %>%
filter(rank <= 2) %>%
ungroup() %>%
select(msg_id, rank) %>%
left_join(test_df, ., by = "msg_id")
# # A tibble: 8 x 6
# group_id msg_id msg_group content parent_id rank
# <dbl> <chr> <chr> <chr> <chr> <dbl>
# 1 1 1 greeting hello <NA> 1
# 2 2 2 greeting hey there <NA> 2
# 3 3 3 greeting morning <NA> NA
# 4 4 4 greeting howdy <NA> NA
# 5 1 5 farewell bye <NA> 1
# 6 2 6 farewell see ya <NA> 2
# 7 1 7 question how are you <NA> 1
# 8 2 8 questions who are you <NA> 1
编辑:也许你不需要join/merge,只需用
就地改变test_df %>%
group_by(msg_group) %>%
mutate(parent_id = if_else(row_number() == 2, msg_id[1], NA_character_))
# # A tibble: 8 x 4
# # Groups: msg_group [3]
# msg_id msg_group content parent_id
# <chr> <chr> <chr> <chr>
# 1 1 greeting hello <NA>
# 2 2 greeting hey there 1
# 3 3 greeting morning <NA>
# 4 4 greeting howdy <NA>
# 5 5 farewell bye <NA>
# 6 6 farewell see ya 5
# 7 7 question how are you <NA>
# 8 8 question who are you 7
(我认为没有必要为 这个 目的创建 rank
列,但这没有坏处。)