Reputation: 40811
Say I have a data frame with the contents:
Trial Person
1 John
2 John
3 John
4 John
1 Bill
2 Bill
3 Bill
4 Bill
and I want to transform this to
Trial Person Day
1 John 1
2 John 1
3 John 2
4 John 2
1 Bill 1
2 Bill 1
3 Bill 2
4 Bill 2
I can very easily make it
Trial Person Day
1 John TRUE
2 John TRUE
3 John FALSE
4 John FALSE
1 Bill TRUE
2 Bill TRUE
3 Bill FALSE
4 Bill FALSE
by doing d$day=d$trial<3
but how can I get to what I want?
Upvotes: 0
Views: 1094
Reputation: 19361
More generally, if you're trying to convert a vector of the form c(1,2,3,4,5,6)
to c(1,1,2,2,3,3)
, as if you had two trials per day, then you might want to express this using integer division:
> x <- 1:6
> x
[1] 1 2 3 4 5 6
> (x-1) %/% 2 + 1
[1] 1 1 2 2 3 3
Upvotes: 1
Reputation: 100164
Get the data:
x <- read.table(textConnection(
"Trial Person
1 John
2 John
3 John
4 John
1 Bill
2 Bill
3 Bill
4 Bill"), header=TRUE)
I think that your current approach is the right one (note: you don't need as.numeric, because it's automatically cast when doing addition in this case):
(x$Trial >= 3) + 1
Otherwise, here's a way to do it with plyr.
library(plyr)
ddply(x, .(Person), transform, Day=rep(c(1,2), each=2))
Upvotes: 1
Reputation: 18864
If you want to be explicit with the assignment (and hard-coding the cutoff of 3), you can use
d$Day <- ifelse(d$trial<3, 1, 2)
This is a bit more transparent. Otherwise, as you discovered, doing an arithmetic operation will convert the logical value to numeric. You can do it yourself by using as.numeric
or as.integer
:
as.integer(FALSE) #0
as.integer(TRUE) #1
Upvotes: 1
Reputation: 40811
Ok, so I found a solution, if I do
(d$trial>=3)+1
It converts the boolean to an integer and it works ... however, is there a better way to do this?
Upvotes: 0