Кто-нибудь может предложить более быстрый способ выполнить итерацию или цикл по этому фрейму данных?

#r

#r

Вопрос:

У меня есть фрейм данных, содержащий примерно 500 000 строк и четыре столбца. Фрейм данных содержит данные о посещениях местоположения конкретным пользователем. Пример фрейма данных приведен ниже:

 > head(data)
  FirstVisit VisitDate                   ID  visit.count
1    40545     40545                 000001        1
2    40545     40545                 000002        1
3    40548     40548                 000003        1
4    40545     40565                 000001        2
5    40545     40575                 000002        2
6    40545     40576                 000002        3
  

Каждое наблюдение содержит первую дату пользователя (в целочисленном формате, где 1 равно 01/01/1900), дату его посещения, его уникальный идентификатор (существует приблизительно 175 000 уникальных идентификаторов) и количество посещений (это их первое посещение, второе посещение и т.д.?). Количество посещений ограничено пятью, поэтому максимальное значение в столбце visit.count меньше или равно пяти. Я хотел бы создать матрицу (или фрейм данных, если необходимо), в которой хранится количество последних посещений для каждого идентификатора; что-то вроде:

 > head(data.matrix)
      ID  visit.count1 visit.count2 visit.count3 visit.count4 visit.count5
1 000001        0            1            0            0            0
2 000002        0            0            1            0            0
3 000003        1            0            0            0            0 
  

Мой код приведен ниже:

 ids <- unique(data$ID)
count.matrix <- matrix(data = 0, nrow = length(ids), ncol = 5)
for (i in 1:length(ids)){
ss <- subset(x = data, subset = data$ID==ids[i])
    ifelse(
            length(rownames(ss))==5, 
            count.matrix[i,5] <- 1, 
            ifelse(
                    length(rownames(ss))==4, 
                    count.matrix[i,4] <- 1, 
                    ifelse(
                            length(rownames(ss))==3, 
                            count.matrix[i,3] <- 1, 
                            ifelse(
                                    length(rownames(ss))==2, 
                                    count.matrix[i,2] <- 1, 
                                    count.matrix[i,1] <- 1
                            )
                    )
            )
    )
}
  

Как я могу улучшить это?

Комментарии:

1. Я переформатировал ваш код, добавив разрывы строк, чтобы его действительно можно было прочитать. Пожалуйста, убедитесь, что это все еще выполняет то, что вы задумали.

2. @Andrie: Спасибо за переформатирование. Сейчас его легче читать, чем когда я публиковал, и код по-прежнему работает так, как я предполагал.

Ответ №1:

Если вам не нужны отдельные столбцы,

 tapply(data$visit.ccount, data$ID, max)
  

должно помочь вам пройти долгий путь.
Если вы это сделаете, вы можете использовать его для создания на нем «версии с разделением на столбцы».

Ответ №2:

Вы могли бы использовать table функцию

 tb <- table(data$ID)
data.matrix <- data.frame(
    ID = names(tb),
    visit.count1 = as.numeric(tb==1),
    visit.count2 = as.numeric(tb==2),
    visit.count3 = as.numeric(tb==3),
    visit.count4 = as.numeric(tb==4),
    visit.count5 = as.numeric(tb==5)
    )
  

Ответ №3:

Если выполнить сортировку по количеству посещений, а затем удалить дубликаты (количество посещений меньше):

 data2 <- data[order(data$visit.count,decreasing=T),]
data2 <- data2[!duplicated(data2$ID),]