Сравните предыдущий элемент списка, используя семейство функций Apply R, избавьтесь от циклов for

Я всегда стараюсь свести к минимуму использование циклов for в R. Есть ли способ сравнить текущий элемент с предыдущим элементом в списке без цикла for? Вот упрощенная версия проблемы, над которой я работаю.

Я хочу отметить столбец First_Transaction как 1, если это первая транзакция человека. Данные уже отсортированы по человеку и дате.

   Name Amount Date First_Transaction 
1   Joe 50  01/05/15    0
2   Joe 43  02/05/15    0
3   Joe 40  03/05/15    0
4   Tom 40  01/03/15    0
5   Tom 34  01/29/15    0
6   Tom 22  02/05/15    0
7   Tom 49  02/10/15    0
8   Kim 28  03/10/15    0
9   Kim 19  03/20/15    0
10  Kim 24  04/13/15    0
11  Kim 35  04/20/15    0

Используя цикл for, я помечаю первую строку 1, а затем использую логику, чтобы проверить, совпадает ли текущее имя с предыдущим. Если это не так, отметьте столбец First_Transaction 1.

test$First_Transaction[1]=1

for(i in 2:length(test$Name)){
  if(test$Name[i] != test$Name[i-1]){
    test$First_Transaction[i]=1
  }

Есть ли функция семейства приложений, которая может реализовать эту логику? Я действительно хочу понять, как это сделать без цикла. Спасибо!


person Max    schedule 11.02.2015    source источник


Ответы (1)


Если первое наблюдение «First_Transaction» следует изменить на «1» для каждой группы «Name», мы могли бы использовать ave

 df1$First_Transaction <- as.numeric(with(df1, 
         ave(seq_along(First_Transaction),Name, FUN=seq_along)==1))

или мы могли бы сравнить текущий элемент «Имя» со следующим элементом

 as.numeric(with(df1, c(TRUE, Name[-1]!=Name[-nrow(df1)])))

Или используйте duplicated

 as.numeric(!duplicated(df1$Name))
person akrun    schedule 11.02.2015