2016-04-06 6 views
1

Я пытаюсь изменить кадр данных для более эффективного хранения и поиска. Каждая строка содержит «родительское» (ключевое) значение, которое не является уникальным между строками и дочерним значением (фактически, набор из 3 атрибутов - 1 символ и 2 цифры). Я хочу преобразовать этот фрейм данных в список, который содержит только одну запись верхнего уровня для каждого уникального родительского ключа, а количество подписок, определяемое количеством дочерних элементов, ассоциируется с родителем. Вот некоторые примерные данные:Как эффективно преобразовать фрейм данных в список списков произвольной длины?

pcm <- data.frame(parent = c("middle", "middle", "might", "might", 
        "might", "million", "million", "millions"), 
       child = c("of", "school", "be", "have", "not", "in", 
        "to", "of"), 
       count = c(476, 165, 1183, 619, 321, 490, 190, 269)) 

Выход для этого должен быть список с 4-х элементов верхнего уровня (называемых "middle", "might", "million", "millions") и различным числом подсписков с именованными членами $child и $count (например lookup4[["middle"]] содержит суб -листов $children[[1]]$child = "of", $count = 476 и $children[[2]]$child = "school", $count = 165).

Приведенный ниже код работает, но очень медленный (несколько часов в кадре данных 300 000 строк с использованием 8 ГБ ОЗУ). Я наложил ограничение 6 на количество детей в выходных данных, но, похоже, это не имело большого значения.

lookup4 <- list() 
parents <- unique(pcm$parent) 
n.parents <- length(parents) 
for (i in 1:n.parents) { 
    words <- pcm$child[pcm$parent == parents[i]] 
    counts <- pcm$count[pcm$parent == parents[i]] 
    probs <- pcm$prob[pcm$parent == parents[i]] 
    n.children <- min(c(NROW(words), 6) 
    ngram.tail <- list() 
    for (k in 1:n.children) { 
     ngram.tail[[k]] <- list(word = words[k], 
     count = counts[k], 
     prob = probs[k]) 
    } 
    lookup4[[parents[i]]] <- list(children = ngram.tail) 
} 

Могу ли я ускорить его, исключив цикл «для»? Если да, то как мне закодировать трансформацию?

+3

Что это 'pcm'? Пожалуйста, покажите небольшой воспроизводимый пример и ожидаемый результат – akrun

+3

. Пожалуйста, прочитайте http://stackoverflow.com/help/mcve, чтобы опубликовать вопрос, который рекомендуется –

+1

'split (pcm [, c (" child "," count "," prob ")], pcm $ parent) 'должен быть первым шагом. Далее, в чем причина наличия множества подписок вместо 'data.frame' с несколькими строками? Я думаю, что выход 'split (...)' должен быть достаточным. – nicola

ответ

0

Попробуйте это:

Я полагаю, что dataframe называется parents:

parents.list <- as.list(as.data.frame(t(parents))) 

Если вы хотите, имена строк родителей, чтобы быть имена в списке:

parents.list <- setNames(split(parents, seq(nrow(parents))), rownames(parents)) 
+0

Спасибо Фелипе, но они не делают того, что я хочу. Имя каждого элемента списка верхнего уровня должно быть уникальным значением «родителей». Я приведу некоторые примеры данных в ближайшее время. – AltShift

Смежные вопросы