[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