Присвоение идентификатора группы с ddply

Довольно основной вопрос о производительности от новичка R. Я хотел бы присвоить идентификатор группы каждой строке в кадре данных уникальными комбинациями полей. Вот мой текущий подход:

> # An example data frame
> df <- data.frame(name=c("Anne", "Bob", "Chris", "Dan", "Erin"), 
                   st.num=c("101", "102", "105", "102", "150"), 
                   st.name=c("Main", "Elm", "Park", "Elm", "Main"))
> df
   name st.num st.name
1  Anne    101    Main
2   Bob    102     Elm
3 Chris    105    Park
4   Dan    102     Elm
5  Erin    150    Main
> 
> # A function to generate a random string
> getString <- function(size=10) return(paste(sample(c(0:9, LETTERS, letters), size, replace=TRUE), collapse=''))
>
> # Assign a random string for each unique street number + street name combination
> df <- ddply(df, 
              c("st.num", "st.name"), 
              function(x) transform(x, household=getString()))
> df
   name st.num st.name  household
1  Anne    101    Main 1EZWm4BQel
2   Bob    102     Elm xNaeuo50NS
3   Dan    102     Elm xNaeuo50NS
4 Chris    105    Park Ju1NZfWlva
5  Erin    150    Main G2gKAMZ1cU

В то время как это работает хорошо на кадры данных с относительно немногими строками или небольшим количеством групп, я сталкиваюсь с проблемами производительности с большими наборами данных (> 100 000 строк), которые имеют многие уникальные группы.

Какие-либо предложения для улучшения скорости этой задачи? Возможно с экспериментальным idata.frame plyr ()? Или я иду об этом неправильно?

Заранее спасибо за Вашу справку.

7
задан danpelota 12 July 2016 в 18:24
поделиться

2 ответа

Попробуйте использовать функция id (также в plyr):

df$id <- id(df[c("st.num", "st.name")], drop = TRUE)

Обновление:

Функция id считается устаревшей, начиная с версии dplyr 0.5.0. Функция group_indices обеспечивает ту же функциональность.

14
ответ дан 6 December 2019 в 12:46
поделиться

Обязательно ли, чтобы идентификатор представлял собой случайную строку из 10 символов? Если нет, почему бы просто не склеить столбцы фрейма данных. Если идентификаторы должны быть одинаковой длины в символах, преобразовать коэффициенты в числовые, а затем вставить их вместе:

df$ID <- paste(as.numeric(df$st.num), as.numeric(df$st.name), sep = "")

Затем, если вам действительно нужно иметь идентификаторы из 10 символов, я бы сгенерировал только n идентификаторов и переименовал уровни идентификатора с ними

df$ID <- as.factor(df$ID)
n <- nlevels(df$ID)

getID <- function(n, size=10){
  out <- {}
  for(i in 1:n){
    out <- c(paste(sample(c(0:9, LETTERS, letters), size, replace=TRUE), collapse=''))
  }
  return(out)
}

newLevels <- getID(n = n)

levels(df$ID) <- newLevels

Кроме того, вам не нужно использовать function (x) с ddply таким образом с transform () . Этот код будет работать точно так же:

ddply(df, c("st.num", "st.name"), transform, household=getString())
2
ответ дан 6 December 2019 в 12:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: