Reputation: 821
Name Grade
John C
John C+
John C
John B
John A
John A+
Kat B
Kat C
Kat B
I want to add a new column, Months
, starting from 3 and then continue with its multiples. The rows are all sorted. The output would look something like
Name Grade Months
John C 3
John C+ 6
John C 9
John B 12
John A 15
John A+ 18
Kat B 3
Kat C 6
Kat B 9
Rcode
name <- df$Name[1]
count <- 0
for (i in 1:length(df[,1])){
if (name!=df$Name[i]){
count <- 0
name <- df$Name[i]
}
df$Months[i] <- count
count <- count + 3
}
Can I do it without a loop?
Upvotes: 2
Views: 310
Reputation: 13570
Another alternative, very similar to Psidom's answer, using seq
with ave
, and 1:nrow(df)
instead of df$Name
to avoid a character vector as an output.
ave(1:nrow(df), df$Name, FUN = seq)*3
# [1] 3 6 9 12 15 18 3 6 9
Upvotes: 1
Reputation: 886948
Using data.table
, convert the 'data.frame' to 'data.table' (setDT(df1)
), grouped by 'Name', assign (:=
) the product of 3 with sequence of rows to 'Months'.
library(data.table)
setDT(df1)[, Months := 3* seq_len(.N) , by = Name]
df1
# Name Grade Months
#1: John C 3
#2: John C+ 6
#3: John C 9
#4: John B 12
#5: John A 15
#6: John A+ 18
#7: Kat B 3
#8: Kat C 6
#9: Kat B 9
Upvotes: 1
Reputation: 214927
You can do a cumulative sum on a vector of 3 grouped by Name
:
with(df, ave(rep(3, length(Name)), Name, FUN = cumsum))
# [1] 3 6 9 12 15 18 3 6 9
Upvotes: 3
Reputation: 3587
Try this
library(dplyr)
df1 %>% group_by(Name) %>% mutate(Months=3*seq(n()))
Upvotes: 5