如何在gather和spread后保持mutate中创建变量的原有顺序?
保持变量顺序与mutate创建顺序一致的解决方案
首先,我注意到你的代码里summarise部分有个小语法错误:round(mean(peanut),这里缺少了第二个参数(比如保留1位小数的1),先修正这个问题,不然代码会直接报错。
回到你的核心问题:默认情况下,gather(或者dplyr旧版本的summarise)会按列名字母顺序处理变量,导致你想要的顺序被打乱。要保持twinkie→peanut→apple→cheese的创建顺序,你可以试试下面几种方法:
方法一:在gather中手动指定变量顺序
不要让gather自动抓取除store和associate之外的所有列,而是按你想要的顺序列出目标变量,这样生成的Metric列就会严格遵循这个顺序:
df %>% mutate( twinkie = var1/60, peanut = var2/60, apple = var3/60, cheese = var4/60 ) %>% group_by(store, associate) %>% summarise( twinkie = mean(twinkie), peanut = round(mean(peanut), 1), # 修正语法错误,补充小数位数参数 apple = round(mean(apple), 1), cheese = round(mean(cheese), 1) ) %>% gather(Metric, value, twinkie, peanut, apple, cheese) %>% # 手动指定变量顺序 spread(associate, value)
方法二:用relocate强制锁定列顺序(dplyr 1.0.0+适用)
如果你的dplyr版本比较新,可以在summarise之后用relocate明确指定列的顺序,再进行后续的gather操作:
df %>% mutate( twinkie = var1/60, peanut = var2/60, apple = var3/60, cheese = var4/60 ) %>% group_by(store, associate) %>% summarise( twinkie = mean(twinkie), peanut = round(mean(peanut), 1), apple = round(mean(apple), 1), cheese = round(mean(cheese), 1) ) %>% relocate(twinkie, peanut, apple, cheese) %>% # 强制按指定顺序排列列 gather(Metric, value, -store, -associate) %>% spread(associate, value)
额外提示:推荐使用pivot_longer替代gather
gather已经是dplyr的旧函数了,官方更推荐用pivot_longer,它在控制顺序上更直观,通过cols参数就能直接指定变量顺序:
df %>% mutate( twinkie = var1/60, peanut = var2/60, apple = var3/60, cheese = var4/60 ) %>% group_by(store, associate) %>% summarise( twinkie = mean(twinkie), peanut = round(mean(peanut), 1), apple = round(mean(apple), 1), cheese = round(mean(cheese), 1) ) %>% pivot_longer( cols = c(twinkie, peanut, apple, cheese), # 指定变量顺序 names_to = "Metric", values_to = "value" ) %>% pivot_wider(names_from = associate, values_from = value)
这样处理后,你的Metric列就会严格遵循你在mutate中创建变量的顺序,不会再被字母排序打乱啦。
内容的提问来源于stack exchange,提问作者zelda26
相关产品推荐
相关产品推荐

