如何在R语言中按分组与日期重新赋值dataframe数据
问题与解决方案
问题背景
我有如下所示的dataframe:
grp1 <- c('A','A','A','A','A','A', 'B','B','B','B','B','B', 'C','C','C','C','C','C') grp2 <- c('PQ2','PQ2','PQ2','PQ2','PQ2','PQ2', 'PL2','PL2','PL2','PL2','PL2','PL2', 'PN2','PN2','PN2','PN2','PN2','PN2') grp3 <- c('ML2','ML2','ML2','ML2','ML2','ML2', 'MP2','MP2','MP2','MP2','MP2','MP2', 'MO2','MO2','MO2','MO2','MO2','MO2') date <- c('2022-04-04','2022-04-05','2022-04-11','2022-04-12','2022-04-18','2022-04-19', '2022-04-04','2022-04-05','2022-04-11','2022-04-12','2022-04-18','2022-04-19', '2022-04-04','2022-04-05','2022-04-11','2022-04-12','2022-04-18','2022-04-19') count <- c(1206, 1432, 333, 292, 1120, 1345, 1100, 1150, 245, 423, 1500, 1400, 1300, 1200, 400, 402, 1100, 1107) df <- data.frame(cbind(grp1, grp2, grp3, date, count))
需求:对每个分组(grp1+grp2+grp3)执行操作:将4月11日的count值替换为对应分组4月4日的count值,将4月12日的count值替换为对应分组4月5日的count值。
解决方案
首先注意:使用cbind创建数据框会把count转为字符型,第一步需要先转换为数值型:
df$count <- as.numeric(df$count)
方法一:使用tidyverse/dplyr(简洁易读)
利用分组后case_when进行条件替换,逻辑清晰直观:
library(dplyr) df_updated <- df %>% group_by(grp1, grp2, grp3) %>% mutate( count = case_when( date == "2022-04-11" ~ count[date == "2022-04-04"], date == "2022-04-12" ~ count[date == "2022-04-05"], TRUE ~ count # 其他日期保持原数值 ) ) %>% ungroup()
方法二:使用data.table(高效适合大数据)
data.table的语法更简洁,处理大数据集时速度优势明显:
library(data.table) setDT(df) # 将普通数据框转为data.table格式 # 直接按条件匹配替换 df[date == "2022-04-11", count := df[.(grp1, grp2, grp3, "2022-04-04"), on = .(grp1, grp2, grp3, date), count]] df[date == "2022-04-12", count := df[.(grp1, grp2, grp3, "2022-04-05"), on = .(grp1, grp2, grp3, date), count]]
补充:基础R方法(无需额外包)
如果不想加载第三方包,也可以用ave函数结合条件判断实现:
df$count <- as.numeric(df$count) df$count <- ave(df$count, df$grp1, df$grp2, df$grp3, FUN = function(x) { group_dates <- df$date[df$grp1 == unique(df$grp1) & df$grp2 == unique(df$grp2) & df$grp3 == unique(df$grp3)] x[group_dates == "2022-04-11"] <- x[group_dates == "2022-04-04"] x[group_dates == "2022-04-12"] <- x[group_dates == "2022-04-05"] x })
不过这种写法不如前两种简洁,适合无法加载第三方包的场景。
内容的提问来源于stack exchange,提问作者user2813606
相关产品推荐
相关产品推荐

