Присвоение идентификатора группы с помощью 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
Хотя это хорошо работает для фреймов данных с относительно небольшим количеством строк или небольшим количеством групп, я столкнулся с проблемами производительности с большими наборами данных ( > 100000 строк), которые имеют много уникальных групп.
Любые предложения по улучшению скорости этой задачи? Возможно, с экспериментальной idata.frame() plyr? Или я все об этом говорю не так?
Заранее спасибо за помощь.
2 ответа
Попробуйте использовать id
функция (также в plyr):
df$id <- id(df[c("st.num", "st.name")], drop = TRUE)
Обновить:
id
функция считается устаревшей, начиная с версии 0.5.0 dplyr. Функция group_indices
обеспечивает ту же функциональность.
Необходимо ли, чтобы идентификатор представлял собой случайную строку из 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())