如何在tidyr spread函数中使用自定义向量作为key参数
解决tidyr::spread使用自定义特征向量作为key的问题
要让spread按照你自己定义的特征向量来生成列,有两种简单好用的方法,我一步步给你演示:
方法1:将feat列转为指定levels的因子
这是最直接的方式,通过把原数据的feat列转换为指定了自定义levels的因子,让spread严格按照你想要的特征名生成列:
首先准备数据和自定义特征列表:
library(tidyr) library(dplyr) # 你的测试数据 test <- data.frame(id=c(1,1,2,2), feat=c("feat1", "feat2", "feat1", "feat2"), value = c(10,20, 1000, 2000)) # 自定义的特征向量,这里我多加了一个feat3作为示例 featlist <- c("feat1", "feat2", "feat3")
然后执行转换和spread操作:
test %>% # 把feat转为因子,强制指定levels为你的自定义列表 mutate(feat = factor(feat, levels = featlist)) %>% spread(key = feat, value = value, fill = 0)
运行后得到的结果:
id feat1 feat2 feat3 1 1 10 20 0 2 2 1000 2000 0
原理说明
- 把
feat转为因子并指定levels后,spread会严格按照这些levels来生成列,哪怕原数据里没有对应的特征(比如这里的feat3),也会保留该列并用fill参数的值填充。 - 如果你的自定义列表里没有包含原数据中的某些feat值,这些值会被自动丢弃(因为因子的levels里没有它们,转换后会变成NA,spread时不会生成对应的列)。
方法2:用complete补全所有自定义特征
如果你希望确保每个id都拥有自定义列表里的所有特征(哪怕原数据中没有),可以先用complete补全缺失的组合,再执行spread:
test %>% # 为每个id补全featlist里的所有特征,缺失的value会设为NA complete(id, feat = featlist) %>% spread(key = feat, value = value, fill = 0)
这个方法得到的结果和方法1完全一样,但它的逻辑是先补全数据行,再做宽表转换,适合需要明确保留所有特征组合的场景。
内容的提问来源于stack exchange,提问作者gabagool
相关产品推荐
相关产品推荐

