如何在R语言中按条件展开dataframe的行?
解决方案
可以使用dplyr和tidyr包实现需求,核心思路是先计算每行的展开次数,再逐组处理时间序列和交替对象:
完整代码
library(dplyr) library(tidyr) # 构造原始数据框 Location <- c("Kitchen", "Living Room", "Living Room", "Garage") Object <- c("Food", "Toy", "Clothes", "Floor") Duration <- c(6,3,2,5) CumDuration <- c(6,9,11,16) Activity <- c("Repetitive", "Constant", "Constant", "Repetitive") df <- data.frame(Location, Object, Duration, CumDuration, Activity) # 预处理:计算展开次数和起始累积时间 df <- df %>% mutate( expand_n = ifelse(Activity == "Repetitive", Duration * 2, 1), start_cum = lag(CumDuration, default = 0) ) # 展开行并生成目标数据框 result_df <- df %>% uncount(expand_n, .id = "row_id") %>% group_by(Location, Object, Activity, start_cum, Duration) %>% mutate( # 重置Duration列 Duration = ifelse(Activity == "Repetitive", 0.5, Duration), # 计算新的累积时长 CumDuration = start_cum + row_id * 0.5, # 交替设置Object值 Object = ifelse(Activity == "Repetitive", ifelse(row_id %% 2 == 1, Object, "Nothing"), Object) ) %>% ungroup() %>% select(Location, Object, Duration, CumDuration, Activity) # 恢复原列顺序 # 查看结果 print(result_df)
代码解释
预处理阶段:
expand_n:根据Activity类型计算每行需要展开的行数,Repetitive类型行的展开次数为Duration*2(每0.5秒一行),Constant类型保持1行。start_cum:记录当前行的起始累积时间,即上一行的CumDuration,第一行默认从0开始。
行展开与列处理:
uncount(expand_n, .id = "row_id"):将每行按照expand_n的次数展开,row_id作为组内的序号,用于后续计算时间和交替对象。- 分组后:
- 重置
Duration:Repetitive行统一设为0.5,Constant行保留原值。 - 计算新的
CumDuration:从start_cum开始,每次累加0.5,确保时间序列连续。 - 交替
Object:利用row_id的奇偶性,奇数行保留原对象,偶数行替换为"Nothing",实现交替效果。
- 重置
- 最后取消分组并恢复原始列顺序,得到目标数据框。
内容的提问来源于stack exchange,提问作者JHo
相关产品推荐
相关产品推荐

