From long to wide form without id.var?

2019-02-26 04:56发布

I have some data in long form that looks like this:

dat1 = data.frame(
  id = rep(LETTERS[1:2], each=4),
  value = 1:8
)

In table form:

id   value
A    1
A    2
A    3
A    4
B    5
B    6
B    7
B    8

And I want it to be in short form and look like this:

dat1 = data.frame(A = 1:4, B = 5:8)

In table form:

A  B
1  5
2  6
3  7
4  8

Now I could solve this by looping with cbind() and stuff, but I want to use some kind of reshape/melt function as these are the best way to do this kind of thing I think.

However, from spending >30 minutes trying to get melt() and reshape() to work, reading answers on SO, it seems that these functions requires the id.var to be set. Now, it is plainly redundant for this kind of thing, so how do I do what I want to do without having to resort to some kind of looping?

标签: r reshape2 melt
3条回答
走好不送
2楼-- · 2019-02-26 05:01

Here's a base R approach to consider. It uses the lengths function, which I believe was introduced in R 3.2.

x <- split(dat1$value, dat1$id)
as.data.frame(lapply(x, function(y) `length<-`(y, max(lengths(x)))))
#   A  B  C
# 1 1  5  7
# 2 2  6  8
# 3 3 NA  9
# 4 4 NA NA
查看更多
forever°为你锁心
3楼-- · 2019-02-26 05:09

I'm pretty sure this has been answered before. Anyway, unstack is convenient in this particular case with equal group size:

unstack(dat1, form = value ~ id)
#   A B
# 1 1 5
# 2 2 6
# 3 3 7
# 4 4 8
查看更多
Luminary・发光体
4楼-- · 2019-02-26 05:25

Solution below works when there are different numbers of As and Bs. For equal counts, unstack works great and with less code (Henrik's answer).

# create more general data (unbalanced 'id')
each <- c(4,2,3)
dat1 = data.frame(
    id = unlist(mapply(rep, x = LETTERS[1:length(each)], each = each)),
    value = 1:sum(each),
    row.names = 1:sum(each) # to reproduce original row.names
)

tab <- table(dat1$id)
dat1$timevar <- unlist(sapply(tab, seq))
library(reshape2)
dcast(dat1, timevar ~ id )[-1]

initial data:

id value
1  A     1
2  A     2
3  A     3
4  A     4
5  B     5
6  B     6
7  C     7
8  C     8
9  C     9

result:

  A  B  C
1 1  5  7
2 2  6  8
3 3 NA  9
4 4 NA NA
查看更多
登录 后发表回答