Nick
Nick

Reputation: 145

Pull Value from Previous Interaction R

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

Answers (3)

CuriousBeing
CuriousBeing

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

Brandon Loudermilk
Brandon Loudermilk

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

akrun
akrun

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

Related Questions