Reputation: 145
Suppose I have the following data.frame:
df <- data.frame(color = c("G","G","G","R","R","R","R","R","R","R","G","G"),
trial = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4))
If I wanted to extract the color
from previous trial
, how would I do that? The ultimate goal would be to end up with a data.frame as such:
color trial prevcolor
1 G 1 <NA>
2 G 1 <NA>
3 G 1 <NA>
4 R 2 G
5 R 2 G
6 R 2 G
7 R 3 R
8 R 3 R
9 R 3 R
10 R 3 R
11 G 4 R
12 G 4 R
Upvotes: 0
Views: 55
Reputation: 1632
Here's another solution using a simple merge
function in R.
Your dataframe:
df <- data.frame(color = c("G","G","G","R","R","R","R","R","R","R","G","G"),
trial = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4))
Now use the merge
function. It is used to merge dataframes only. Hence:
df2<-merge(data.frame(prevtrial=c(df$trial-1)),unique(df), by.x="prevtrial",by.y="trial",all.x=T)
Now create a new dataframe for your output:
newdf<-data.frame(color=df$color,trial=df$trial,prevtrial=df2$prevtrial,prevcolor=df2$color)
which will give:
> newdf
color trial prevtrial prevcolor
1 G 1 0 <NA>
2 G 1 0 <NA>
3 G 1 0 <NA>
4 R 2 1 G
5 R 2 1 G
6 R 2 1 G
7 R 3 2 R
8 R 3 2 R
9 R 3 2 R
10 R 3 2 R
11 G 4 3 R
12 G 4 3 R
>
Upvotes: 0
Reputation: 970
Here's a solution using a for
loop:
df <- data.frame(color = c("G","G","G","R","R","R","R","R","R","R","G","G"),
trial = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4))
# iterate through trial numbers
for (trial in unique(df$trial)) {
# select color of previous trial number
prev_color <- as.character(df$color[df$trial == trial - 1])[1]
# assign previous color to current trial number
df$prevcolor[df$trial == trial] <- prev_color
}
df
## color trial prevcolor
##1 G 1 <NA>
##2 G 1 <NA>
##3 G 1 <NA>
##4 R 2 G
##5 R 2 G
##6 R 2 G
##7 R 3 R
##8 R 3 R
##9 R 3 R
##10 R 3 R
##11 G 4 R
##12 G 4 R
Upvotes: 1
Reputation: 887158
We could use lag
(assuming that the 'trial' is ordered)
df$prevcolor <- with(df, lag(color, n=sum(trial==trial[1L])))
df
# color trial prevcolor
#1 G 1 <NA>
#2 G 1 <NA>
#3 G 1 <NA>
#4 R 2 G
#5 R 2 G
#6 R 2 G
#7 R 3 R
#8 R 3 R
#9 R 3 R
#10 R 3 R
#11 G 4 R
#12 G 4 R
A variant of @rawr's solution in the comments (in case the 'trial' is not a numeric column)
Un1 <- unique(df$trial)
with(df, color[match(factor(trial, levels= Un1, labels = c(NA, head(Un1,-1))), trial)])
With dplyr
, we can use group_indices
to get the index of the group
library(dplyr)
df %>%
mutate(prev_color = color[match(group_indices_(.,.dots = 'trial')-1, trial)])
# color trial prev_color
#1 G 1 <NA>
#2 G 1 <NA>
#3 G 1 <NA>
#4 R 2 G
#5 R 2 G
#6 R 2 G
#7 R 3 R
#8 R 3 R
#9 R 3 R
#10 R 3 R
#11 G 4 R
#12 G 4 R
Upvotes: 1