broccoli
broccoli

Reputation: 4836

ddply for transforming data

I've the following test data frame.

id1 val
A 1  
A 1  
A 1  
A 1  
B 2  
B 2  
B 2  
B 2  

I would like to transform it to a data frame as shown below.

id1 val
A 1  
A 1  
A 2  
A 2  
B 3  
B 3  
B 4  
B 4  

What I've done is to first find the count of the number of times A & B occur, in this case = 4, split that into 2 and then update the second column so that it gets incremented accordingly. So the four 1's have become 1,2, the four 2's have become 3,4 and so on. I know this fits the SAC paradigm, but wondering how to do it with ddply. Any suggestions please? Thanks much in advance

Upvotes: 1

Views: 307

Answers (1)

G Chalancon
G Chalancon

Reputation: 306

First, let's get your sample object:

d <- data.frame( id1= c(rep("A",4), rep("B",4)),  val=c(rep("1",4), rep("2",4)) )

A convenient way to do what you seem to want would simply be to do:

> d$val <- rep( 1:(nrow(d)/2), each=2)
> d
  id1 val
1   A   1
2   A   1
3   A   2
4   A   2
5   B   3
6   B   3
7   B   4
8   B   4

And that's it.

A reason to use a split-apply-combine approach would be to have a numbering that specifically depends on the combinations of column values, for instance. With ddply you could split rows according to id1 and val, and for get a different type of numbering:

f <- function(x){ rep(1:(length(x)/2), each=2) }
ddply(d, .(id1), transform, val = f(val) )

   id1 val
1   A   1
2   A   1
3   A   2
4   A   2
5   B   1
6   B   1
7   B   2
8   B   2

Working on the definition of fand doing the arithmetics would certainly lead you to a solution, but if the following assumptions describe what you want:

  • an increment of +1 every 2 rows
  • A and B always occur in even numbers

then I don't see the point... applying rep(x, each=2) to d does the job!

Upvotes: 1

Related Questions