Jump to content
agfac

Gerar intervalos e agrupar valores

Recommended Posts

agfac

Boa tarde,

No âmbito da minha tese de mestrado preciso de elaborar tabelas a partir um volume gigantesco de dados. A ideia é agrupar os dados por intervalos por forma a tornar exequível a consultar desses dados através de tabelas.

Apresento em seguida 2 imagens:

- Na 1ª imagem constam os dados em bruto;

Dados_brutos1.jpg

- Na 2ª imagem constam os dados agrupados:

Dados_agrupados1.jpg

Este agrupamento foi feito manualmente e demorou muito tempo. Como tal, precisava de arranjar uma forma automática de gerar os intervalos e fazer o agrupamento.

Desde já agradeço a quem me tentar ajudar. Obrigado.

Cumps

Share this post


Link to post
Share on other sites
HappyHippyHippo

porque razão que isto está na secção de XML ? os dados estão em XML ?

XML é uma markup language, não serve para fazer computação.

como pretendes realizar a pretendido ? aplicação ? uma página web ?

  • Vote 1

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
agfac

Sim, os dados estão em xml. Mas posso converte-los no que for preciso por forma a resolver o meu problema.

Pretendia um código ou uma aplicação que conseguisse agrupar os dados gerando os intervalos.

Share this post


Link to post
Share on other sites
Rui Carlos

Ainda não percebi ao certo as fórmulas que tens que usar, mas com um pouco sorte até numa coisa tipo o Excel consegues fazer isso.

Mas para começar, convinha explicares a lógica usada para compactar os dados. Os intervalos são fixos? Para a última coluna é feita uma média, ou é suposto os valores serem todos iguais?

Share this post


Link to post
Share on other sites
HappyHippyHippo

Pretendia um código ou uma aplicação que conseguisse agrupar os dados gerando os intervalos.

essa resposta é demasiado vaga.

o que dizes pode se situar em espectros completamente diferentes em termos de resolução.

tens de ser mais específico no que pretendes em termos de caminho a seguir


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
agfac

Não, os intervalos não são fixos. O objectivo é gerar os intervalos dos parâmetros de entrada (área (m2), l (m) e efetivo máximo) consoante o valor da última coluna (fator) seja o mesmo.

O resultado final deve ser uma tabela igual à da 2ª imagem.

A 1ª imagem é um pequeno excerto dos dados.

O parâmetro de entrada área pode assumir os seguintes valores: 9, 16, 25, 36, 50, 64, 75, 100, 125, 150, 175 e 200.

Para cada uma das áreas o comprimento pode assumir os seguintes valores: 5, 10, 15, 20 e 30.

E para cada um dos comprimentos, o efetivo máximo pode assumir os seguintes: 3, 6, 10, 15, 20, 30, 50, 75, 100, 125, 150, 175 e 200.

Apesar destes parâmetros variarem, o resultado final (fator) pode ser o mesmo. Assim, pretendo estabelecer os intervalos dos parâmetros cujo fator seja o mesmo.

Share this post


Link to post
Share on other sites
Rui Carlos

Que o resultado que pretendes é a segunda tabela penso que já toda a gente percebeu. A questão é: qual é o algoritmo/método/... que usas para determinares os intervalos da tabela?

O que é que te leva a criar mais ou menos divisões?

É que pelos dados não é fácil adivinhar o algoritmo, até porque há alguns valores que parecem não bater certo com o resultado (não esperaria que a primeira coluna só tivesse um valor).

Penso que a colocação dos dados numa BD SQL é capaz de ajudar (o SQL é uma boa linguagem para manipular tabelas, e o algoritmo em que estou a pensar seria baseado na operação GROUP BY do SQL).

Share this post


Link to post
Share on other sites
agfac

Os critérios para a definição dos intervalos foram 2:

1º - agrupar os parâmetros cujo valor do fator (última coluna) seja o mesmo;

2º - conseguir o menor número de intervalos possível.

Como o agrupamento foi feito à mão, por vezes alterei alguns valores do fator (sempre para um valor superior) se isso me permitisse obter um menor número de intervalos.

Penso que para utilizar o comando sugerido (GROUP BY) seja necessário fornecer os intervalos. Ora, aquilo que eu pretendo é que os intervalos sejam gerados automaticamente.

Edited by agfac

Share this post


Link to post
Share on other sites
Rui Carlos

A ideia do GROUP BY é determinar se é necessário dividir um intervalo.

Assumindo que tinhas uma tabela com as colunas ap, l, e e f, a query

select sum(equals)
  from (select max(f) <> min(f) as equals
            from vals
            group by l,e) as eq;

determinava se era necessário dividir com base em ap. Basicamente a query verifica se agrupando por l e e é suficiente para definir os valores de f (e deverá devolver 0 se for o caso).

O passo seguinte seria fazer um teste semelhante com base em l, usando a query

select sum(equals)
   from (select max(f) <> min(f) as equals
             from vals
             group by e) as eq;

Mas neste caso a query não devolvia 0, o que significava que ias ter que começar a testar diferentes intervalos. Ora se o l pode assumir 5, 10, 15, ... vais tentando queries do género:

select sum(equals)
   from (select max(f) <> min(f) as equals
             from vals
             where l > 0 and l <= 30
             group by e) as eq;

e vais reduzindo o 30 (para 20, 15, 10, ...) até que a query devolva 0. Quando isso acontecer, esse valores definirão um dos intervalos. Alterando os limites irás obter os restantes intervalos.

De seguida ias fazer algo semelhante com o e.

O ideal seria construíres uma script que te fazia todos estes testes automaticamente.

Possivelmente haverá formas mais simples de resolver o problema, mas esta foi a primeira que me lembrei.

Share this post


Link to post
Share on other sites
agfac

Experimentei começar a fazer um código para resolver o meu problema mas o agrupamento não está a ser feito devidamente.

Alguém me consegue ajudar?

data <- data.frame(n1=rep(c(16), each=15), n2=rep(c(5,10,15,20,30), 3), n3=rep(c(3,6,10), each=5), f=c(17, 18, 20, 17, 18, 20, 18, 18, 19, 18, 18, 19, 17, 18, 19))

group.level <- function(data, c)
{
n <- data[,c]
f <- data[,ncol(data)]

splits <- which(f[2:length(f)] != f[1:(length(f)-1)]) + 1
grouped.i <- sapply(2:(length(splits)+2), function(i, splits)
 {
  seq(splits[i-1], splits[i] - 1)
 }, c(1, splits, length(f)+1))
new.n <- sapply(grouped.i, function(i, n) {
  paste(sep=".", n[i], collapse="-")
 }, n)
new.data <- data[c(1, splits), ]
new.data[,c] <- as.factor(new.n)
new.data
}
# assumes 3 levels
group <- function(data)
{
aggr1 <- group.level(data[order(data[,1], data[,2], data[,3]),], 3)
aggr2 <- group.level(aggr1[order(aggr1[,3], aggr1[,1], aggr1[,2]),], 2)
group.level(aggr2[order(aggr2[,2], aggr2[,3], aggr2[,1]),], 1)
}

group(data)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.