[R-br] Evolução de elementos em grupos
Roney Fraga Souza
roneyfraga em gmail.com
Terça Junho 10 13:29:11 BRT 2014
Éder, bom dia!
Quanto ao código que mandei ontem, vi que estava criando um data.frame() dentro de um for que não deveria, isso fez o código ficar excessivamente lento, foi erro meu. Alterar isso permitiu melhorar a performance do código, mas ainda assim não consegui fazer os cálculos com todos os dados que tenho. Segue código corrigido.
###
### início do código
###
grupo <- list()
system.time({
for(k in 2:length(ver2)){
grp <- sort(unique((ver2[[k-1]]$grupo))) ### qtde de grupos
grp2 <- sort(unique((ver2[[k]]$grupo))) ### qtde de grupos
# criando os objetos
RES <- LAB <- list()
for (i in grp) {
for (j in grp2) {
RES <- append(RES,list( subset(ver2[[k-1]]$name, ver2[[k-1]]$grupo==i) %in% subset(ver2[[k]]$name, ver2[[k]]$grupo==j)))
LAB <- append(LAB, paste(i,j, sep='-'))
}}
grupo[[k]] <- data.frame(label=sapply(LAB, "["), qtde=sapply(RES, sum))
grupo[[k]] <- subset(grupo[[k]],qtde>0)
grupo[[k]]$t.grupo <- as.numeric(gsub('-.*','',grupo[[k]]$label))
grupo[[k]]$t.ano <- min(ver2[[k]]$year)+k-2
grupo[[k]]$tp1.grupo <- as.numeric(gsub('^.-','',grupo[[k]]$label))
grupo[[k]]$tp1.ano <- min(ver2[[k]]$year)+k-1
}
})
###
### fim do código
###
Quanto a sugestão de trabalhar direto com data.frame, tentei utilizar o código inicial que você gentilmente fez mudando o input para data.frame, veja o código:
###
### início do código
###
# na minha lista original de data.frames cada data.frame da lista representa um ano, sendo que o primeiro ano da lista é para 1978 e o último é 2013.
# a lista é cumulativa, logo, os artigos de 1978 parecem em todos os anos subsequentes, por exemplo, no ano de 1986 aparecem os artigos de
# 1978 até 1986.
# a constituição dos grupos ocorre pode mudar para cada artigo ao longo do tempo. Exemplo, um artigo de “Yunos, 1997, V19, P255”
# pode fazer parte do grupo 1 em 1997, do grupo 2 em 1998, do grupo 13 em 2005, etc.
# para diferenciar os anos criei uma variável ‘ano.base’
#
for(i in 1:length(ver2)){
ver2[[i]]$ano.base <- 1977+i
}
ver.df <- do.call(rbind, ver2)
row.names(ver.df) <- NULL
head(ver.df)
dim(ver.df)
str(ver.df)
grupo <- list()
system.time({
for(k in (1+min(ver.df$ano.base)):max(ver.df$ano.base)){
grp <- max(ver.df$grupo[ver.df$ano.base==k-1])
grp2 <- max(ver.df$grupo[ver.df$ano.base==k])
# criando os objetos
RES <- LAB <- list()
for (i in 1:grp) {
for (j in 1:grp2) {
RES <- append(RES,list(ver.df$name[ver.df$ano.base==k-1 & ver.df$grupo==i] %in% ver.df$name[ver.df$ano.base==k & ver.df$grupo==j]))
LAB <- append(LAB, paste(i,j, sep='-'))
}}
grupo[[k]] <- data.frame(
label=sapply(LAB, "["),
qtde=sapply(RES, sum),
t.ano=k-1,
tp1.ano=k
)
grupo[[k]] <- subset(grupo[[k]],qtde>0)
# deletar os valores NULL
# pq ele gerar todos os anos antes de 1978 com NULL
grupo <- grupo[ -(which(sapply(grupo,is.null), arr.ind=TRUE))]
}
grupo <- do.call(rbind, grupo)
dim(grupo)
})
###
### fim do código
###
Utilizando o primeiro código (lista de data.frames) tenho a resposta em 15 segundos, quando utilizo o segundo código (o input é um único data.frame) demora 2min35s. Vale considerar que quando transformo a lista de data.frames em um único data.frame "do.call(rbind, ver2)” este tem 37136 linhas.
Bem, os códigos funcionam muito bem, a questão é o tempo de processamento. Minha base de dados completa, quando faço ”do.call(rbind, ver2)” tem 2531107 linhas, que são os artigos publicados entre 1945 e 2013.
Meu problema é, cada ano tem vários grupos, quero saber quantos artigos tem origem de cada grupo do ano anterior “t-1”, isso para cada grupo do ano t.
Éder, quanto ao último código que você mandou, vou estudá-lo.
Agradeço pela atenção.
Roney
Mais detalhes sobre a lista de discussão R-br