2013-11-17 3 views
0

У меня есть этот набор последовательностей с 2 ​​переменными для третьей переменной (устройства). Теперь я хочу, чтобы разбить последовательность для каждого устройства в наборы 300. dsl представляет собой кадр данных, который содержит d быть идентификатор устройства и s является количество последовательностей длины 300.Избегайте вложенных циклов в R

Во-первых, я мечения (колонка Sid) все последовательности rep(1,300), за которыми следует rep(2,300) и т. д. до rep(s,300). Все, что остается незамеченным, то есть с инициализированными метками (= 0), нужно игнорировать. Фактическая маркировка происходит только с seqid.

Мне нужно было сделать это, поскольку я хочу складывать наборы из 300 точек данных, а затем транспонировать их. Это сформировало бы один ряд моих данных predata data.frame. Для каждого кадра данных predata я делаю k-средство для создания 5 кластеров, которые храню в конечных данных.

По существу для каждого устройства у меня будет 5 кластеров, которые я могу извлечь, указав номер строки в окончательных данных (сопоставленных с идентификатором устройства).

#subset processed data by device 

for (ds in 1:387){ 
    d <- dsl[ds,1] 
    s <- dsl[ds,3] 

    temp.data <- subset(data,data$Device==d) 
    temp.data$Sid <- 0 
    temp.data[1:(s*300),4] <- rep(1:300,s) 
    temp.data <- subset(temp.data,temp.data$Sid!="0") 

    seqid <- NA 

    for (j in 1:s){ seqid[(300*(j-1)+1):(300*j)] <- j } 

    temp.data$Sid <- seqid 

    predata <- as.data.frame(matrix(numeric(0),s,600)) 


    for(k in 1:s){ 
    temp.data2 <- subset(temp.data[,c(1,2)], temp.data$Sid==k) 
    predata[k,] <- t(stack(temp.data2)[,1]) 
    } 

    ob <- kmeans(predata,5,iter.max=10,algorithm="Hartigan-Wong") 
    finaldata <- rbind(finaldata,(unique(fitted(ob,method="centers")))) 
} 

Будучи нуб к R, я закончил с 3 вложенных циклов (функция сделал работу для внешней петли будучи одно значение). Это заняло 5 часов и работает. Нужен более быстрый способ сделать это.

Любая помощь будет оценена по достоинству.

Благодаря

+0

Можете ли вы [предоставить образец вашего набора данных] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example)? 'головка (данные)'? Трудно разобрать, что происходит. – bnjmn

ответ

0

Хорошо, я собираюсь предложить радикальное упрощение кода внутри цикла. Тем не менее, трудно проверить, что я действительно принял правильное решение, не имея пробных данных. Поэтому, пожалуйста, убедитесь, что мой predata фактически равен вашим.

Первый код:

for (ds in 1:387){ 
    d <- dsl[ds,1] 
    s <- dsl[ds,3] 

    temp.data <- subset(data,data$Device==d) 
    temp.data <- temp.data[1:(s*300),] 

    predata <- cbind(matrix(temp.data[,1], byrow=T, ncol=300), matrix(temp.data[,2], byrow=T, ncol=300)) 

    ob <- kmeans(predata,5,iter.max=10,algorithm="Hartigan-Wong") 
    finaldata <- rbind(finaldata,(unique(fitted(ob,method="centers")))) 
} 

Я понимаю, что вы делаете: Возьмите первые 300*s элементы из вашего subset(data, data$Devide == d. Это может быть легко сделано с помощью команды

temp.data <- temp.data[1:(s*300),] 

Затем вы собираете матрицу, которая имеет первую строку c(temp.data[1:300, 1], temp.data[1:300, 2]), и так далее для всех последующих строк. Я делаю это с помощью команды matrix, как указано выше.

Я предполагаю, что ваш внешний цикл может быть преобразован в вызов tapply или что-то подобное, но, следовательно, нам понадобится больше контекста.

+0

Я понимаю, что есть несколько циклов. Я думаю, что основной камень преткновения в этом заключается в том, чтобы найти способ использования встроенной функции R, такой как «tapply», которая приведет к разрушению данных, обработке фрагментов и сборке в отдельной переменной. Если есть конкретный способ сделать это, тогда это может быть применено к проблеме. Это возможно? – user2977721

+0

@ user2977721 Вы пробовали мою версию выше? В зависимости от размера '' ', мы могли бы уже сэкономить довольно много времени. Чтобы упростить внешний цикл, нам определенно нужен больше контекста и, вероятно, образец данных. Однако я боюсь, что «kmeans» также может стать частью узкого места. – Thilo

+0

Еще одно замечание: попробуйте профилировать цикл, используя 'Rprof'. Если большинство времени теряется с помощью команды 'subset' и' rbind', некоторая версия 'apply' может ускорить процесс.Если узким местом является «kmeans», у вас будет совершенно другая задача. Генерация 'predata', как указано выше, не требует много времени. – Thilo

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