我收集了一个数据框,用于模拟组问题解决会话中事件的持续时间,其中成员进行通信(Discourse Code
)并构建模型(Modeling Code
)。发生的每一分钟都会在Time_Processed
列中捕获。从技术上讲,这些事件同时发生我想知道学生构建每种模型的时间有多长,即模型的总持续时间或模型变化之前经过的时间。
我有以下数据集:
看起来像这样:
`Modeling Code` `Discourse Code` Time_Processed
<fct> <fct> <dbl>
1 OFF OFF 10.0
2 MA Q 11.0
3 MA AG 16.0
4 V S 18.0
5 V Q 20.0
6 MA C 21.0
7 MA C 23.0
8 MA C 25.0
9 V J 26.0
10 P S 28.0
# My explicit dataframe.
df <- structure(list(`Modeling Code` = structure(c(3L, 2L, 2L, 6L,
6L, 2L, 2L, 2L, 6L, 4L), .Label = c("A", "MA", "OFF", "P", "SM",
"V"), class = "factor"), `Discourse Code` = structure(c(7L, 8L,
1L, 9L, 8L, 2L, 2L, 2L, 6L, 9L), .Label = c("AG", "C", "D", "DA",
"G", "J", "OFF", "Q", "S"), class = "factor"), Time_Processed = c(10,
11, 16, 18, 20, 21, 23, 25, 26, 28)), row.names = c(NA, -10L), .Names = c("Modeling Code",
"Discourse Code", "Time_Processed"), class = c("tbl_df", "tbl",
"data.frame"))
对于这个数据框,我可以找到学生在逻辑上像这样构建每种模型的频率。
尊重Modeling Code
和Time_Processed
列,
在10分钟他们使用OFF模型方法,然后在11分钟,他们改变模型,因此OFF模型的持续时间是(11-10)分钟= 1分钟。没有其他“OFF”方法,所以持续时间OFF = 1分钟。
同样,对于建模代码方法“MA”,模型使用时间为11分钟到16分钟(持续时间= 5分钟),然后是16分钟到18分钟,然后模型变为V(持续时间= 2分钟) ,然后该模型在21分钟再次使用,并在26分钟结束(持续时间= 5分钟)。所以“MA”的总持续时间是(5 + 2 + 5)分钟= 12分钟。
同样,建模代码方法“V”的持续时间从18分钟开始,到21分钟结束(持续时间= 3分钟),在26分钟恢复,在28分钟(持续时间= 2)分钟结束。所以“V”的总持续时间是3 + 2 = 5分钟。
然后,建模代码P的持续时间从28分钟开始并且没有连续性,因此 P的总持续时间为0分钟。
因此,建模代码的总持续时间(分钟)表是:
Modeling Code Total_Duration
OFF 1
MA 12
V 5
P 0
这会模拟如下所示的条形图:
如何构建这些建模方法的总持续时间?
了解组合的持续时间也很好 这个小子集中唯一可见的组合恰好是建模代码“MA”与话语码“C”配对,这种情况发生在26-21 = 5分钟。
谢谢。
答案 0 :(得分:2)
更新的解决方案
df %>%
mutate(dur = lead(Time_Processed) - Time_Processed) %>%
replace_na(list(dur = 0)) %>%
group_by(`Modeling Code`) %>%
summarise(tot_time = sum(dur))
(^感谢Nick DiQuattro)
以前的解决方案
这是一个创建新变量mcode_grp
的解决方案,它可以跟踪同一Modeling Code
的离散分组。它不是特别漂亮 - 它需要在df
中的每一行循环 - 但它有效。
首先,重命名列以便于参考:
df <- df %>%
rename(m_code = `Modeling Code`,
d_code = `Discourse Code`)
我们会使用一些额外的变量来更新df
- lead_time_proc
为Time_Processed
中的下一行提供了df
值,这是我们在计算每个m_code
批次的总时间时所需要的。 />
- row_n
用于跟踪迭代中的行号
- mcode_grp
是每个m_code
批次的唯一标签
df <- df %>%
mutate(lead_time_proc = lead(Time_Processed),
row_n = row_number(),
mcode_grp = "")
接下来,我们需要一种方法来跟踪我们何时达到给定m_code
值的新批次。一种方法是为每个m_code
保留一个计数器,并在达到新批次时递增计数器。然后我们可以将该m_code
批次的所有行标记为属于同一时间窗口。
mcode_ct <- df %>%
group_by(m_code) %>%
summarise(ct = 0) %>%
mutate(m_code = as.character(m_code))
这是最丑陋的部分。我们遍历df
中的每一行,然后检查我们是否已达到新的m_code
。如果是,我们会相应更新,并为每行注册mcode_grp
的值。
mc <- ""
for (i in 1:nrow(df)) {
current_mc <- df$m_code[i]
if (current_mc != mc) {
mc <- current_mc
mcode_ct <- mcode_ct %>% mutate(ct = ifelse(m_code == mc, ct + 1, ct))
current_grp <- mcode_ct %>% filter(m_code == mc) %>% select(ct) %>% pull()
}
df <- df %>% mutate(mcode_grp = ifelse(row_n == i, current_grp, mcode_grp))
}
最后,group_by
m_code
和mcode_grp
计算每个批次的持续时间,然后将m_code
值相加。
df %>%
group_by(m_code, mcode_grp) %>%
summarise(start_time = min(Time_Processed),
end_time = max(lead_time_proc)) %>%
mutate(total_time = end_time - start_time) %>%
group_by(m_code) %>%
summarise(total_time = sum(total_time)) %>%
replace_na(list(total_time=0))
输出:
# A tibble: 4 x 2
m_code total_time
<fct> <dbl>
1 MA 12.
2 OFF 1.
3 P 0.
4 V 5.
对于那里的任何dplyr
/ tidyverse
专家,我都喜欢如何在不诉诸循环和计数器的情况下完成更多工作的技巧!