Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pasting values from a vector to a new column in a for loop with nested data

I have a dataframe that currently looks like this:

subjectID Trial
1 3
1 3
1 3
1 4
1 4
1 5
1 5
1 5
2 1
2 1
2 3
2 3
2 3
2 5
2 5
2 6
3 1

Etc., where trial number is nested under subject ID. I need to make a new column in which column "NewTrial" is simply what order the trials now appear in. For example:

subjectID Trial NewTrial
1 3 1
1 3 1
1 3 1
1 4 2
1 4 2
1 5 3
1 5 3
1 5 3
2 1 1
2 1 1
2 3 2
2 3 2
2 3 2
2 5 3
2 5 3
2 6 4
3 1 1

So far, I have a for-loop written that looks like this:

for (myperson in unique(data$subjectID)){

#This line creates a vector of the number of unique trials per subject: for subject 1, c(1, 2, 3)
triallength=1:length(unique(data$Trial[data$subID==myperson]))

I'm having trouble now finding a way to paste the numbers from the created triallength vector as a column in the dataframe. Does anyone know of a way to accomplish this? I am lacking some experience with for-loops and hoping to gain more. If anyone has a tidyverse/dplyr solution, however, I am open to that as well as an alternative to a for-loop. Thanks in advance, and let me know if any clarification is needed!

like image 999
Paul Avatar asked Oct 14 '25 15:10

Paul


2 Answers

Converting to factor with unique values as levels, then as.numeric in an ave should be nice.

transform(dat, NewTrial=ave(Trial, subjectID, FUN=\(x) as.numeric(factor(x, levels=unique(x)))))
#    subjectID Trial NewTrial
# 1          1     3        1
# 2          1     3        1
# 3          1     3        1
# 4          1     4        2
# 5          1     4        2
# 6          1     5        3
# 7          1     5        3
# 8          1     5        3
# 9          2     1        1
# 10         2     1        1
# 11         2     3        2
# 12         2     3        2
# 13         2     3        2
# 14         2     5        3
# 15         2     5        3
# 16         2     6        4
# 17         3     1        1

Data:

dat <- structure(list(subjectID = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L), Trial = c(3L, 3L, 3L, 4L, 
4L, 5L, 5L, 5L, 1L, 1L, 3L, 3L, 3L, 5L, 5L, 6L, 1L)), class = "data.frame", row.names = c(NA, 
-17L))
like image 127
jay.sf Avatar answered Oct 17 '25 04:10

jay.sf


We could use match on the unique values after grouping by 'subjectID'

library(dplyr)
df1 <- df1 %>% 
  group_by(subjectID) %>%
  mutate(NewTrial = match(Trial, unique(Trial))) %>%
  ungroup
like image 36
akrun Avatar answered Oct 17 '25 04:10

akrun