wil*_*ter 6 r dataframe reshape2
我是R的新手,可以选择轻松地重新组织数据,并且已经找到了解决方案但却找不到我想要做的事情.Reshape2的熔化/铸造看起来似乎不起作用,我还没有很好地掌握了它在这里的因素.
基本上我有一个data.frame,其结构如下所示,带有一个category列,其中每个元素都是一个可变长度的类别列表(更紧凑,因为#columns更大,我实际上有多个category_lists,我喜欢分开):
>mydf
ID category_list xval yval
1 ID1 cat1, cat2, cat3 xnum1 ynum1
2 ID2 cat2, cat3 xnum2 ynum2
3 ID3 cat1 xnum3 ynum3
Run Code Online (Sandbox Code Playgroud)
我想用类别作为因子(和相关的值,即列3/4)进行操作,所以我认为我最终需要这样的东西,其中ID和x/y /其他列值根据类别列表的长度:
ID category xval yval
1 ID1 cat1 xnum1 ynum1
2 ID1 cat2 xnum1 ynum1
3 ID1 cat3 xnum1 ynum1
4 ID2 cat2 xnum2 ynum2
5 ID2 cat3 xnum2 ynum2
6 ID3 cat3 xnum2 ynum2
Run Code Online (Sandbox Code Playgroud)
如果在category_list上有另一个因子/方面的解决方案,那将是一个更简单的解决方案,但我没有遇到支持这个的方法,例如以下引发错误
>ggplot(mydf, aes(x=x, y=y)) + geom_point() + facet_grid(~cat_list)
Run Code Online (Sandbox Code Playgroud)
layout_base中的错误(data,cols,drop = drop):至少一个图层必须包含用于构面的所有变量
谢谢!
答案取决于格式category_list.如果实际上list每行都是一个
就像是
mydf <- data.frame(ID = paste0('ID',1:3),
category_list = I(list(c('cat1','cat2','cat3'), c('cat2','cat3'), c('cat1'))),
xval = 1:3, yval = 1:3)
Run Code Online (Sandbox Code Playgroud)
要么
library(data.table)
mydf <- as.data.frame(data.table(ID = paste0('ID',1:3),
category_list = list(c('cat1','cat2','cat3'), c('cat2','cat3'), c('cat1')),
xval = 1:3, yval = 1:3) )
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用plyr和merge创建长格式数据
newdf <- merge(mydf, ddply(mydf, .(ID), summarize, cat_list = unlist(category_list)), by = 'ID')
ID category_list xval yval cat_list
1 ID1 cat1, cat2, cat3 1 1 cat1
2 ID1 cat1, cat2, cat3 1 1 cat2
3 ID1 cat1, cat2, cat3 1 1 cat3
4 ID2 cat2, cat3 2 2 cat2
5 ID2 cat2, cat3 2 2 cat3
6 ID3 cat1 3 3 cat1
Run Code Online (Sandbox Code Playgroud)
或者不需要的非plyr方法 merge
do.call(rbind,lapply(split(mydf, mydf$ID), transform, cat_list = unlist(category_list)))
Run Code Online (Sandbox Code Playgroud)
一个缓慢但看似强大的解决方案:
## Some example data
df <- as.data.frame(cbind(ID = paste0("ID", 1:2),
category_list = list(4:1, 2:3),
xvar = 8:9,
yvar = 10:9))
## Calculate number of times each row of df will be repeated
nn <- sapply(df$category_list, length)
ii <- rep(seq_along(nn), times=nn)
## Reshape data.frame
transform(df[ii,],
category = unlist(df$category_list),
category_list = NULL,
row.names = NULL)
# ID xvar yvar category
# 1 ID1 8 10 4
# 2 ID1 8 10 3
# 3 ID1 8 10 2
# 4 ID1 8 10 1
# 5 ID2 9 9 2
# 6 ID2 9 9 3
Run Code Online (Sandbox Code Playgroud)