#r #dplyr #tidyverse
#r #dplyr #tidyverse
Вопрос:
В данных ключевыми переменными являются: ‘слушатель’ и ‘динамик’. Первый прослушиватель, наблюдаемый для каждого «потока», является исходным автором потока.
Я пытаюсь создать отдельную переменную «участие автора», которая помечает в двоичном формате (0, 1) строки, в которых автор потока был говорящим.
Тестовые данные:
structure(list(topic = c(1, 1, 1, 1, 2, 2, 2, 2, 2, 2), thread = c(10,
10, 10, 10, 3, 3, 3, 3, 3, 3), listener = c(111, 111, 222, 111,
222, 444, 333, 222, 444, 222), speaker = c(222, 333, 111, 444,
444, 333, 222, 333, 222, 444)), class = "data.frame", row.names = c(NA,
-10L), codepage = 65001L)
Конечный результат будет выглядеть так:
╔═══════╦════════╦══════════╦═════════╦════════════════════╦═══════════════════════════════════════════════════════════════╗
║ topic ║ thread ║ listener ║ speaker ║ writer_involvement ║ explanation ║
╠═══════╬════════╬══════════╬═════════╬════════════════════╬═══════════════════════════════════════════════════════════════╣
║ 1 ║ 10 ║ 111 ║ 222 ║ 0 ║ The first observed listener (111) is the writer of the thread ║
╠═══════╬════════╬══════════╬═════════╬════════════════════╬═══════════════════════════════════════════════════════════════╣
║ 1 ║ 10 ║ 111 ║ 333 ║ 0 ║ ║
╠═══════╬════════╬══════════╬═════════╬════════════════════╬═══════════════════════════════════════════════════════════════╣
║ 1 ║ 10 ║ 222 ║ 111 ║ 1 ║ The writer of this thread, 111, spoke here ║
╠═══════╬════════╬══════════╬═════════╬════════════════════╬═══════════════════════════════════════════════════════════════╣
║ 1 ║ 10 ║ 111 ║ 444 ║ 0 ║ ║
╠═══════╬════════╬══════════╬═════════╬════════════════════╬═══════════════════════════════════════════════════════════════╣
║ 2 ║ 3 ║ 222 ║ 444 ║ 0 ║ The first observed listener (222) is the writer ║
╠═══════╬════════╬══════════╬═════════╬════════════════════╬═══════════════════════════════════════════════════════════════╣
║ 2 ║ 3 ║ 444 ║ 333 ║ 0 ║ ║
╠═══════╬════════╬══════════╬═════════╬════════════════════╬═══════════════════════════════════════════════════════════════╣
║ 2 ║ 3 ║ 333 ║ 222 ║ 1 ║ The writer of this thread, 222, spoke here ║
╠═══════╬════════╬══════════╬═════════╬════════════════════╬═══════════════════════════════════════════════════════════════╣
║ 2 ║ 3 ║ 222 ║ 333 ║ 0 ║ ║
╠═══════╬════════╬══════════╬═════════╬════════════════════╬═══════════════════════════════════════════════════════════════╣
║ 2 ║ 3 ║ 444 ║ 222 ║ 1 ║ The writer of this thread, 222, spoke here ║
╠═══════╬════════╬══════════╬═════════╬════════════════════╬═══════════════════════════════════════════════════════════════╣
║ 2 ║ 3 ║ 222 ║ 444 ║ 0 ║ ║
╚═══════╩════════╩══════════╩═════════╩════════════════════╩═══════════════════════════════════════════════════════════════╝
Ответ №1:
Мы можем использовать match
с nomatch= 0
после группировки по «теме»
library(dplyr)
df %>%
group_by(topic) %>%
mutate(write_involvement = match(speaker, first(listener), nomatch = 0)) %>%
ungroup
-вывод
# A tibble: 10 x 5
# topic thread listener speaker write_involvement
# <dbl> <dbl> <dbl> <dbl> <int>
# 1 1 10 111 222 0
# 2 1 10 111 333 0
# 3 1 10 222 111 1
# 4 1 10 111 444 0
# 5 2 3 222 444 0
# 6 2 3 444 333 0
# 7 2 3 333 222 1
# 8 2 3 222 333 0
# 9 2 3 444 222 1
#10 2 3 222 444 0
Или создайте логический вывод и принудительно преобразуйте в двоичный
df %>%
group_by(topic) %>%
mutate(write_involvement = (speaker == first(listener)))
Ответ №2:
Базовый параметр R, использующий ave
within(
df,
writer_involvement <- (ave(listener, topic, thread, FUN = function(x) head(x, 1)) == speaker)
)
дает
topic thread listener speaker writer_involvement
1 1 10 111 222 0
2 1 10 111 333 0
3 1 10 222 111 1
4 1 10 111 444 0
5 2 3 222 444 0
6 2 3 444 333 0
7 2 3 333 222 1
8 2 3 222 333 0
9 2 3 444 222 1
10 2 3 222 444 0
Опция data.table
setDT(df)[, writer_involvement := (speaker == head(listener, 1)), .(topic, thread)]
дает
> df
topic thread listener speaker writer_involvement
1: 1 10 111 222 0
2: 1 10 111 333 0
3: 1 10 222 111 1
4: 1 10 111 444 0
5: 2 3 222 444 0
6: 2 3 444 333 0
7: 2 3 333 222 1
8: 2 3 222 333 0
9: 2 3 444 222 1
10: 2 3 222 444 0