15
votes
$\begingroup$

I'm having following problem while doing some analysis with R.

I have a dataframe like this:

Name | Group | Count
Person 1 | A | 3
Person 2 | A | 1
Person 3 | A | 0
Person 1 | B | 5 
Person 2 | B | 0
Person 3 | B | 1
Person 1 | C | 1

and I'd need to "expand" it (not sure if the right term) to be like this:

Person 1 | A
Person 1 | A
Person 1 | A
Person 2 | A
Person 1 | B
Person 1 | B

etc.

So it takes value of pair Person 1 and A (in this example, 3) and makes three rows with Person 1 and A and does so for every Person - Group -combination. Can't figure out any good words for searching online.

$\endgroup$

locked by whuber Jun 20 '18 at 15:55

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site, so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. More info: help center.

Read more about locked posts here.

  • $\begingroup$ Try the reshape() function $\endgroup$ – guest Mar 23 '12 at 15:43
  • $\begingroup$ You should explore the reshape2 package in R. It might also help to dput 2 example dataframes: one with the input and one with the output. $\endgroup$ – Zach Mar 23 '12 at 15:45
  • $\begingroup$ I provided an answer but I guess this more of an R programming question than a statistical question, so maybe it should be migrated somewhere else. $\endgroup$ – Gala Mar 23 '12 at 16:11
  • $\begingroup$ Thanks Gaël for answer and helping with the formatting in my question. $\endgroup$ – Juha-Matti S. Mar 23 '12 at 16:46
10
votes
$\begingroup$

While it is a very useful package, I think reshape is overkill in this case, rep can do the job.

Here are some example data:

df <- data.frame(
     name=c("Person 1", "Person 2", "Person 3", "Person 1", "Person 2", "Person 3"),
     group=c("A", "A", "A", "B", "B", "B"),
     count=c(3,1,0,5,0,1))

Now, to “expand” it:

expanded <- data.frame(name = rep(df$name, df$count),
                       group = rep(df$group, df$count))

I could not find a way to work directly on the data frame off the top of my head so I am working on each variable separately and then reassembling them, which is a bit ugly but should be OK as long as you take care of always using the same variable for the counts.

$\endgroup$
  • 7
    $\begingroup$ How about this: df[rep(seq_len(nrow(df)), df$count), 1:2]? $\endgroup$ – chl Mar 23 '12 at 17:19
  • $\begingroup$ @chl, you sir are brilliant! $\endgroup$ – Chris Oct 12 '16 at 1:34
15
votes
$\begingroup$

You can use the untable function from the reshape package.

Given the above df (by @Gaël Laurans)

library(reshape)

expanded<-untable(df[,c(1,2)], num=df[,3])

name group
1   Person 1     A
1.1 Person 1     A
1.2 Person 1     A
2   Person 2     A
4   Person 1     B
4.1 Person 1     B
4.2 Person 1     B
4.3 Person 1     B
4.4 Person 1     B
6   Person 3     B
$\endgroup$
  • $\begingroup$ untable does exactly what I mentioned in my comment :-) Thanks for reminding me of that function! $\endgroup$ – chl Mar 24 '12 at 20:32
1
vote
$\begingroup$

And uncount from tidyr now gives the same result as above.

library(tidyr)
df %>% uncount(Count)
$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.