Evolução de elementos em grupos

Caros, Estou tentando resolver um problema que nem sei por onde começar. Tenho dois data.frame()
data1 name grupo 1 Banker, 1986, V32, P1613 1 2 Banker, 1986, V32, P30 1 3 Macmillan, 1986, V60, P41 1 4 Charnes, 1985, V30, P91 1 5 Sherman, 1985, V9, P297 3 6 Nunamaker, 1985, V6, P50 2 7 Sherman, 1984, V4, P35 3 8 Banker, 1984, V17, P35 1 9 Banker, 1984, V30, P1078 1 10 Nunamaker, 1983, V18, P183 2 11 Parks, 1983, V12, P337 2 12 Charnes, 1981, V27, P668 3 13 Bessent, 1980, V16, P57 2 14 Charnes, 1978, V2, P429 1
data2 name grupo 1 Sengupta, 1987, V18, P2279 2 2 Sengupta, 1987, V8, P93 2 3 Thanassoulis, 1987, V38, P397 1 4 Sengupta, 1987, V14, P117 2 5 Banker, 1986, V32, P1613 1 6 Banker, 1986, V32, P30 1 7 Macmillan, 1986, V60, P41 1 8 Charnes, 1985, V30, P91 1 9 Sherman, 1985, V9, P297 3 10 Nunamaker, 1985, V6, P50 2 11 Sherman, 1984, V4, P35 3 12 Banker, 1984, V17, P35 1 13 Banker, 1984, V30, P1078 1 14 Nunamaker, 1983, V18, P183 2 15 Parks, 1983, V12, P337 3 16 Charnes, 1981, V27, P668 3 17 Bessent, 1980, V16, P57 2 18 Charnes, 1978, V2, P429 1
e desejo comparar quantos elementos de cada grupo de data2 fazem parte de cada grupo de data1. Tentando ser mais claro: #quantos elementos de subset(data2, grupo==1) # fazem parte de subset(data1, grupo==1) subset(data1, grupo==2) subset(data1, grupo==3) #depois o raciocínio se repete para o grupo 2 de data2 #quantos elementos de subset(data2, grupo==2) # fazem parte de subset(data1, grupo==1) subset(data1, grupo==2) subset(data1, grupo==3) Por fim, desejo acompanhar quanto o grupo 1 do objeto data1 contribuiu para constituir o grupo 1 do objeto data2, e assim por diante. Para baixar esses dados, segue link: http://www.datafilehost.com/d/4428e6f8 Atenciosamente Roney

Caro Roney, bom dia! Segue uma primeira ideia. Verifique se atende... ### <code> # setwd(choose.dir()) # load('dados.RData') head(data1); head(data2) grp <- sort(unique(c(data1$grupo, data2$grupo))) ### grupos {RES <- LAB <- list() for (i in grp) { for (j in grp) { RES <- append(RES,list( subset(data2$name, data2$grupo==i) %in% subset(data1$name, data1$grupo==j))) LAB <- append(LAB, paste(i,j, sep='-')) }}} data.frame(label=sapply(LAB, "["), res=sapply(RES, sum), total=sapply(RES, length)) ### </code> Éder Comunello <c <comunello.eder@gmail.com>omunello.eder@gmail.com> Dourados, MS - [22 16.5'S, 54 49'W] Em 10 de maio de 2014 11:40, Roney Fraga Souza <roneyfraga@gmail.com>escreveu:
Caros,
Estou tentando resolver um problema que nem sei por onde começar.
Tenho dois data.frame()
data1 name grupo 1 Banker, 1986, V32, P1613 1 2 Banker, 1986, V32, P30 1 3 Macmillan, 1986, V60, P41 1 4 Charnes, 1985, V30, P91 1 5 Sherman, 1985, V9, P297 3 6 Nunamaker, 1985, V6, P50 2 7 Sherman, 1984, V4, P35 3 8 Banker, 1984, V17, P35 1 9 Banker, 1984, V30, P1078 1 10 Nunamaker, 1983, V18, P183 2 11 Parks, 1983, V12, P337 2 12 Charnes, 1981, V27, P668 3 13 Bessent, 1980, V16, P57 2 14 Charnes, 1978, V2, P429 1
data2 name grupo 1 Sengupta, 1987, V18, P2279 2 2 Sengupta, 1987, V8, P93 2 3 Thanassoulis, 1987, V38, P397 1 4 Sengupta, 1987, V14, P117 2 5 Banker, 1986, V32, P1613 1 6 Banker, 1986, V32, P30 1 7 Macmillan, 1986, V60, P41 1 8 Charnes, 1985, V30, P91 1 9 Sherman, 1985, V9, P297 3 10 Nunamaker, 1985, V6, P50 2 11 Sherman, 1984, V4, P35 3 12 Banker, 1984, V17, P35 1 13 Banker, 1984, V30, P1078 1 14 Nunamaker, 1983, V18, P183 2 15 Parks, 1983, V12, P337 3 16 Charnes, 1981, V27, P668 3 17 Bessent, 1980, V16, P57 2 18 Charnes, 1978, V2, P429 1
e desejo comparar quantos elementos de cada grupo de data2 fazem parte de cada grupo de data1. Tentando ser mais claro:
#quantos elementos de subset(data2, grupo==1) # fazem parte de subset(data1, grupo==1) subset(data1, grupo==2) subset(data1, grupo==3)
#depois o raciocínio se repete para o grupo 2 de data2 #quantos elementos de subset(data2, grupo==2) # fazem parte de subset(data1, grupo==1) subset(data1, grupo==2) subset(data1, grupo==3)
Por fim, desejo acompanhar quanto o grupo 1 do objeto data1 contribuiu para constituir o grupo 1 do objeto data2, e assim por diante.
Para baixar esses dados, segue link: http://www.datafilehost.com/d/4428e6f8
Atenciosamente Roney _______________________________________________ R-br mailing list R-br@listas.c3sl.ufpr.br https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.

Pessoal, bom dia! Estou com um pequeno problema de tempo de processamento e gostaria da opinião de vocês para verificar se é possível diminuí-lo. A questão que busco solucionar é a mesma descrita na primeira mensagem desse post. Com a ajuda de Éder o problema foi previamente solucionado, contudo, agora estou com uma base de dados maior e o tempo de processamento explodiu. Segue uma versão pequena dos dados para teste. Link para download. https://dl.dropboxusercontent.com/u/61883020/ver2.RData Att Roney ### ### início do código ### load(‘ver2.RData’) grupo <- list() # system.time({ for(k in 2:length(a)){ grp <- sort(unique(c(ver2[[k-1]]$grupo, ver2[[k]]$grupo))) ### qtde de grupos # criando os objetos RES <- LAB <- list() for (i in grp) { for (j in grp) { 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]] <- subset( data.frame( label=sapply(LAB, "["), qtde=sapply(RES, sum)), qtde>0 ) }} grupo[[k]]$tm1.grupo <- as.numeric(gsub('-.*','',grupo[[k]]$label)) grupo[[k]]$tm1.ano <- min(ver2[[k]]$year)+k-2 grupo[[k]]$t.grupo <- as.numeric(gsub('^.-','',grupo[[k]]$label)) grupo[[k]]$t.ano <- min(ver2[[k]]$year)+k-1 } }) ### ### fim do código ###

Pessoal, só para lembrar, estou rondado essa rotina em um macbook pro i7 com 16 gb de ram e em um desktop arch linux i7 tb com 16 gb de ram. Minha lista original tem as seguintes dimensões:
lapply(ver2, dim) [[1]] [1] 36 4
[[2]] [1] 101 4 [[3]] [1] 170 4 [[4]] [1] 237 4 [[5]] [1] 315 4 [[6]] [1] 401 4 [[7]] [1] 499 4 [[8]] [1] 596 4 [[9]] [1] 693 4 [[10]] [1] 800 4 [[11]] [1] 876 4 [[12]] [1] 978 4 [[13]] [1] 1121 4 [[14]] [1] 1278 4 [[15]] [1] 1404 4 [[16]] [1] 1558 4 [[17]] [1] 1772 4 [[18]] [1] 1943 4 [[19]] [1] 2130 4 [[20]] [1] 2313 4 [[21]] [1] 2534 4 [[22]] [1] 2781 4 [[23]] [1] 3087 4 [[24]] [1] 3438 4 [[25]] [1] 3876 4 [[26]] [1] 4328 4 [[27]] [1] 4772 4 [[28]] [1] 5267 4 [[29]] [1] 5763 4 [[30]] [1] 6283 4 [[31]] [1] 6838 4 [[32]] [1] 7393 4 [[33]] [1] 8014 4 [[34]] [1] 8674 4 [[35]] [1] 9428 4 [[36]] [1] 10267 4 [[37]] [1] 11137 4 [[38]] [1] 12120 4 [[39]] [1] 13177 4 [[40]] [1] 14288 4 [[41]] [1] 15490 4 [[42]] [1] 16757 4 [[43]] [1] 18036 4 [[44]] [1] 19265 4 [[45]] [1] 20573 4 [[46]] [1] 22111 4 [[47]] [1] 25943 4 [[48]] [1] 29779 4 [[49]] [1] 33784 4 [[50]] [1] 38085 4 [[51]] [1] 42641 4 [[52]] [1] 47746 4 [[53]] [1] 52833 4 [[54]] [1] 58237 4 [[55]] [1] 63574 4 [[56]] [1] 68923 4 [[57]] [1] 74475 4 [[58]] [1] 80363 4 [[59]] [1] 86464 4 [[60]] [1] 93170 4 [[61]] [1] 100144 4 [[62]] [1] 107785 4 [[63]] [1] 116178 4 [[64]] [1] 125932 4 [[65]] [1] 136335 4 [[66]] [1] 148238 4 [[67]] [1] 162200 4 [[68]] [1] 177071 4 [[69]] [1] 192734 4 [[70]] [1] 193555 4

Roney, boa tarde! Sugiro trabalhar com um data.frame único ao invés da lista de data.frames. ver2.df <- do.call(rbind, ver2) row.names(ver2.df) <- NULL ver2.df str(ver2.df) # 'data.frame': 37136 obs. of 4 variables: # $ name : chr "Charnes, 1978, V2, P429" "Charnes, 1978, V2, P429" "Bessent, 1980, V16, P57" "Charnes, 1978, V2, P429" ... # $ year : num 1978 1978 1980 1978 1981 ... # $ grupo: num 1 1 1 1 1 1 1 1 1 1 ... # $ one : num 1 1 1 1 1 1 1 1 1 1 ... Pra uma ideia rápida da ocorrência da referência nos grupos: tab <- table(ver2.df$name, ver2.df$grupo); head(tab) Éder Comunello <c <comunello.eder@gmail.com>omunello.eder@gmail.com> Dourados, MS - [22 16.5'S, 54 49'W]

Roney, bom dia! Complementando o email anterior... ### <code r> setwd("C:/LAB/Temp/Roney");getwd() load("ver2.RData") ver2.df <- do.call(rbind, ver2) row.names(ver2.df) <- NULL head(ver2.df) str(ver2.df) ### ideia básica table(ver2.df$name, ver2.df$grupo) ### transforma table em data.frame tab <- as.data.frame.matrix(table(ver2.df$name, ver2.df$grupo)); head(tab) ### conferindo alguns resultados apresentados em tab... tab[2,1:5] lapply(1:5, function(x) ver2.df[which(ver2.df$name=='Abay, 2004, V24, P123'&ver2.df$grupo==x),]) ### número de citações de cada referência rowSums(tab[,2:48]) ### número de grupos em que citação ocorre tabL <- (tab>0)*1 ; head(tabL) ### criação de uma versão "lógica" de tab rowSums(tabL[,2:48]) ### situações em que a citação do grupo 1 aparece no grupo 2 nrow(tab[tabL[,1]&tabL[,2],1:2]) #[1] 2173 tab[tabL[,1]&tabL[,2],1:2] ### situações em que a citação do grupo 1 aparece no grupo 3 nrow(tab[tabL[,1]&tabL[,3],c(1,3)]) #[1] 1827 tab[tabL[,1]&tabL[,3],c(1,3)] ### você pode utilizar um loop pra testar cada grupo contra os demais! ### </code> Éder Comunello <c <comunello.eder@gmail.com>omunello.eder@gmail.com> Dourados, MS - [22 16.5'S, 54 49'W]

É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

Éder, utilizando a função intersect() o tempo de processamento reduziu pela metade. ### ### início do código ### load(‘ver2.RData”) grupo <- list() system.time({ for(k in 2:length(ver2)){ grp <- sort(unique((ver2[[k-1]]$grupo))) ### qtde de grupos no ano t-1 grp2 <- sort(unique((ver2[[k]]$grupo))) ### qtde de grupos no ano t RES <- LAB <- list() for (i in grp) { for (j in grp2) { RES <- append(RES,list(length(intersect(ver2[[k-1]]$name[ver2[[k-1]]$grupo==i], 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 } }) grupo[[8]] # resultado para o ano de 1985 ### ### fim ### Quanto ao tempo total de processamento, em: RES <- append(RES,list(length(intersect(ver2[[k-1]]$name[ver2[[k-1]]$grupo==i], ver2[[k]]$name[ver2[[k]]$grupo==j])))) o tempo gasto é de aproximadamente 72% do total, enquanto em: LAB <- append(LAB, paste(i,j, sep=‘-')) o tempo gasto é de aproximadamente 22% do tempo total. Penso então que para melhorar o código é necessário ter uma função que compare elementos entre grupos mais rápida que intersect(). Alguém conhece alguma? Att Roney

Roney, bom dia! Agora pude ter uma ideia melhor do seu trabalho. Pelo volume de dados acho que cai no que o pessoal se refere como 'big data'. Nessa área tem várias recomendações de pacotes que já vi aqui na lista, sendo que já tive oportunidade de ver alguma coisa com o pacote {data.table}. Transformando os dados em um data.table() ao invés de data.frame(), o processamento é agilizado, desde que empregada a sintaxe correta. Até onde sei, todas as funções que aceitam data.frame() trabalham com data.table(), mas a forma de uso tem algumas diferenças. Não sei se você dispõe de tempo pra isso nesse momento, mas minha sugestão é tentar ajustar os dados para data.table() e avaliar o desempenho no script elaborado para trabalhar inicialmente com o data.frame. Se tiver interesse, sugiro criar um tópico novo tentando capturar a atenção do pessoal da lista que tem experiência com uso de 'big data'. Éder Comunello <c <comunello.eder@gmail.com>omunello.eder@gmail.com> Dourados, MS - [22 16.5'S, 54 49'W]

Éder, bom dia! Preciso terminar algumas análises para essa base de dados que estou trabalhando com certa urgência, daí vou deixar esse problema para resolver no futuro. Mas como você já indicou o caminho que devo seguir, esta mais fácil agora. Quando conseguir algum resultado expressivo posto aqui. Valeu pela ajuda. Roney
participantes (2)
-
Roney Fraga Souza
-
Éder Comunello