Velocidade de computação em R?

16

Fui encarregado de mudar um dos nossos grandes modelos estocásticos atuais do SAS para um novo idioma. Pessoalmente, prefiro uma linguagem compilada tradicional, mas o PI quer que eu verifique o R, que nunca usei. Nossa motivação para tirar o modelo do SAS é (1) muitas pessoas não têm acesso a ele porque o SAS é caro, (2) estamos procurando nos afastar de uma linguagem interpretada e (3) o SAS é lento para o tipo de modelo que temos.

Para (1), obviamente, R satisfaz a necessidade de ser livre. Para (2), idealmente, gostaríamos de criar um executável, mas R é normalmente usado como uma linguagem de script. Vejo que alguém lançou recentemente um compilador R - isso foi bem recebido? Isso é fácil de usar? Preferimos não forçar o usuário a baixar o próprio R. Para (3), nosso problema com o SAS é todo o tempo gasto na gravação e leitura de conjuntos de dados de E / S. Nosso modelo é computacionalmente intensivo e geralmente somos limitados pelo tempo de execução. (por exemplo, não é incomum alguém sequestrar computadores das pessoas no fim de semana para executar execuções.) Temos um modelo semelhante construído no Fortran que não tem o mesmo problema porque todo o trabalho é feito na memória. Como o R funciona? Será o mesmo que o SAS, na medida em que funciona em etapas de dados, lendo e gravando arquivos? Ou ele pode manipular matrizes na memória?

Melissa
fonte
Geralmente, você pode acelerar o sas fazendo todo o seu trabalho em uma única etapa de dados. Isso deve reduzir o tempo de E / S, pois você efetivamente lê apenas os dados uma vez. O uso de muitos procedimentos também o atrasará. Por exemplo, se você modelar chamar repetidamente proc glm ou proc logistic (por exemplo, para uma inicialização), é mais rápido criar um grande conjunto de dados e usar uma instrução by do que invocar muitas chamadas proc (por exemplo, usando uma macro% loop). se você programar bem sas, você não deveria estar tendo problemas de tempo de execução devido à leitura e outputing arquivos (pelo menos não mais do que o outro software
probabilityislogic
Além disso, você pode usar matrizes temporárias em passos dados sas de uma forma semelhante à forma como você usaria matrizes em R.
probabilityislogic

Respostas:

18

R funciona na memória - portanto, seus dados precisam caber na memória para a maioria das funções.

O pacote do compilador, se eu estiver pensando no que você está pensando (o compilador de Luke Tierney pacote fornecido com R), não é o mesmo que uma linguagem compilada no sentido tradicional (C, Fortran). É um compilador de bytes para R no sentido de bytecode Java executado pela Java VM ou compilação de bytes do código Emacs LISP. Ele não compila o código R no código da máquina, mas prepara o código R no código de bytes para que possa ser usado com mais eficiência do que o código R bruto a ser interpretado.

Observe que se você tiver formado o Fortran, provavelmente terá o melhor dos dois mundos; R pode chamar rotinas Fortran compiladas.

Restabelecer Monica - G. Simpson
fonte
Obrigado! É bom saber que eu poderia ter ótimos gráficos R e chamar rotinas compiladas do Fortran. Esta pode ser a resposta!
Melissa
2
Apenas para expandir a observação de Gavin sobre memória: consulte a seção Memória Grande nesta visualização de tarefa CRAN, se você estiver trabalhando com conjuntos de dados maiores: cran.r-project.org/web/views/HighPerformanceComputing.html
Brandon Bertelsen
11
Também pense que é importante observar que o Rcpp provavelmente poderia ser usado para obter ganhos incrementais no desempenho.
Brandon Bertelsen
O Rcpp é útil para agrupar C ++ para uso em / com R. Ele ajuda o processo (imensamente), mas ainda está usando as ferramentas básicas de R para chamar código compilado. Se o OP já tiver códigos ou habilidades em Fortran, o Rcpp poderá ser de menor utilidade.
Reintegrar Monica - G. Simpson
13

Eu uso SAShá 15 anos e comecei a usar Rseriamente nos últimos 6 meses, com alguns ajustes nele por alguns anos antes disso. Do ponto de vista da programação, R as manipulações de dados são feitas diretamente, não há procedimentos DATAou equivalentes PROC SQLporque elas não são necessárias (a última sendo mais eficiente SASquando há muita manipulação de dados a partir de fontes de dados externas, por exemplo, dados administrativos). Isso significa que, agora estou entendendo, a manipulação de dados é mais rápida Re requer muito menos código.

O principal problema que encontrei é a memória. Nem todos os pacotes R permitem WEIGHTespecificações de tipo; portanto, se você tiver SASconjuntos de dados com variáveis ​​usadas em FREQou REPLICATEinstruções, poderá haver problemas. Eu observei os pacotes ffe bigmemoryno R, mas eles não parecem ser compatíveis com todos os pacotes R; portanto, se você tiver conjuntos de dados muito grandes que exijam análises relativamente incomuns e que tenham sido agregados, poderá haver problemas com a memória.

Para automação, se você tiver SAS macros, poderá programar o equivalente Re executar como lote.

Para codificação R, eu estava usando Notepad++e definindo o idioma para R, e agora estou descobrindo as alegrias de R Studio. Ambos os produtos são gratuitos e marcam o idioma como a SASGUI de sintaxe aprimorada (só usei a tela de sintaxe SAS).

Existe um site e um livro relacionado para as pessoas que trocam de SASpara R. Eu os achei úteis para tentar descobrir como traduzir alguns SAScomandos R.

Update: uma coisa que me deixou maluco quando chegar a Ré que Rnão assume tudo é um conjunto de dados ( data frameno Rjargão), porque não é um pacote estatístico do modo que SAS, SPSS, Stata, etc, são. Então, por exemplo, levei um tempo para que as ifinstruções funcionassem porque eu continuava recebendo ajuda para ifdeclarações com vetores (ou talvez matrizes), enquanto eu precisava de uma ifdeclaração que funcionasse data frames. Portanto, as páginas de ajuda provavelmente precisam ser lidas mais atentamente do que você normalmente, porque você precisará verificar se o comando que deseja executar funcionará com o tipo de objeto de dados que você possui.

O pouco que ainda me deixa maluco ao aprender um novo Rcomando (por exemplo, método de análise em um pacote contribuído) é que a ajuda para comandos geralmente não é totalmente independente. Irei à página de ajuda para tentar aprender o comando e as notas de uso geralmente ...contidas neles. Às vezes, tentar descobrir o que pode ou deve ir aonde ...está me leva a um ciclo recursivo. A brevidade relativa das notas de ajuda, provenientes da SASqual fornece exemplos detalhados de sintaxe e exemplos trabalhados com uma explicação do estudo no exemplo, foi um choque bastante grande.

Michelle
fonte
2
+1 Considere atualizar nosso meta thread, onde coletamos links para recursos de software de estatísticas. Há uma resposta para o R e outra para o SAS: os dois se beneficiariam de ter um link para r4stats.com. (Esse fio é realmente uma parte do nosso FAQ Esperamos mantê-lo atualizado e útil..)
whuber
11
O R também possui pacotes que oferecem suporte ao acesso ao SQL por meio de drivers RODBC ou SQLite.
Dwin
11
Eu concordo com seus comentários sobre a ajuda do R. Na verdade, apontei essencialmente o que você está dizendo em uma das listas de discussão do R há muitos anos. A resposta não foi positiva. Para ser justo, eu (a) provavelmente não me expressei muito bem e não dei exemplos concretos e (b) não levei a cabo o assunto. Para resumir, o problema 1 é exemplos muito complicados e envolvem muitos conceitos não relacionados. Exemplos complicados são aceitáveis, mas devem seguir exemplos simples. O problema 2 é que quase não há anotações ou explicações sobre o que os exemplos fazem.
Faheem Mitha
Em relação à R "ajuda", lembre-se de algo que meu chefe me disse. "você aprende R por fazê-lo com alguém que já conhece R sentada ao seu lado no computador"
probabilityislogic
E para todos os outros, existem livros e Stack Overflow. Sim, aprender R sozinho é bastante difícil, pelo menos tem sido para mim.
31512 Michelle
10

R é uma linguagem de programação. Não funciona em etapas de dados. Ele faz o que você quer que faça, pois é apenas uma linguagem de programação, uma escrava de seus desejos, expressa em uma linguagem de colchetes e dois pontos.

Pense nisso como Fortran ou C, mas com vetorização implícita para que você não precise repetir matrizes e gerenciamento dinâmico de memória para não precisar malloc () ou declarar tamanhos de matriz a qualquer momento.

Na maioria das vezes, ele faz todo o trabalho na memória, mas se você quiser ler parte de um arquivo, use-o, cuspa alguns dos resultados e leia o próximo fragmento, bem, vá em frente e escreva um programa R que faz isso.

Você se contradiz ao dizer que o modelo é computacionalmente intensivo, mas o SAS é lento por causa de E / S ... Um ou outro certamente ...

Se você já tem algo semelhante no Fortran e diz que deseja se afastar de uma linguagem interpretada, por que não fazê-lo também no Fortran?

O compilador R pode causar algumas acelerações, mas se seu código R for bem escrito, você não obterá nada muito grande - não é como escrever em C ou Fortran.

Spacedman
fonte
Ah, não me expliquei bem. É intenso na manipulação de conjuntos de dados, o que no SAS significa muito tempo gasto em E / S. Minha sugestão inicial foi Fortran, mas o PI está interessado em mudar para R, então ele queria que eu desse uma olhada. Obrigado!
Melissa
7

Entendo que, por padrão, o SAS pode trabalhar com modelos maiores que a memória, mas esse não é o caso do R, a menos que você use especificamente pacotes como biglm ou ff.

No entanto, se você estiver fazendo um trabalho de matriz em R que possa ser vetorizado, será muito rápido - talvez metade da velocidade de um programa C em alguns casos, mas se você estiver fazendo algo que não pode ser vetorizado, isso parecerá bastante lento. Para dar um exemplo:

# create a data.frame with 4 columns of standard normally distributed RVs
N <- 10000

# test 1
system.time( {df1 <- data.frame(h1=rnorm(N),
                h2=rpois(N, lambda=5),
                h3=runif(N),
                h4=rexp(N))
} )
# about 0.003 seconds elapsed time

# vectorised sum of columns 1 to 4
# i.e. it can work on an entire column all at once
# test 2
system.time( { df1$rowtotal1 <- df1$h1 + df1$h2 + df1$h3 + df1$h4 })
# about 0.001 seconds elapsed time

# test 3
# another version of the vectorised sum
system.time( { df1$rowtotal2 <- rowSums(df1[,c(1:4)]) })
# about 0.001 seconds elapsed time

# test 4
# using a loop... THIS IS *VERY* SLOW AND GENERALLY A BAD IDEA!!! :-)
system.time( {
        for(i in 1:nrow(df1)) {
                df1$rowtotal3 <- df1[i,1]+ df1[i,2] + df1[i,3] + df1[i,4]
        }
} )
# about 9.2 seconds elapsed time

Quando aumentei N em um fator de dez a 100.000, desisti do teste 4 após 20 minutos, mas os testes 1: 3 fizeram 61, 3 e 37 milissegundos cada

Para N = 10.000.000, o tempo para os testes 1: 3 são 3.3s, 0.6s e 1.6s

Observe que isso foi feito em um laptop i7 e a 480mb para N = 10 milhões, a memória não era um problema.

Para usuários em janelas de 32 bits, existe um limite de memória de 1,5 GB para R, independentemente da quantidade de memória que você possui, mas não existe esse limite para janelas de 64 bits ou linux de 64 bits. Hoje em dia, a memória é muito barata em comparação com o custo de uma hora do meu tempo, então compro mais memória em vez de gastar tempo tentando contornar isso. Mas isso pressupõe que seu modelo caiba na memória.

Sean
fonte
11
(+1) Obrigado por oferecer as ilustrações úteis, Sean!
whuber
3

(2), idealmente, gostaríamos de criar um executável, mas R é normalmente usado como uma linguagem de script

Sim, e esse é o bom motivo para mudar para R. O interesse de escrever um pacote R é permitir que os usuários façam suas funções interagirem facilmente com outras ferramentas fornecidas pelo R, por exemplo, alimentando-os com dados de inicialização ... ou o que eles quiserem. Se você acha que isso não é importante, atenha-se ao C / C ++ ou à sua linguagem compilada favorita.

Quero acrescentar uma ressalva: você já é um programador, aprender R será fácil e rápido; aprender programação R eficiente será mais longo. Como R é interpretado, as constantes ocultas noO() da complexidade assintótica pode ser grande ou pequena ... por exemplo, se você estiver interessado em execuções em seus dados, usará rle() , elas serão rápidas (é uma função pré-compilada). Se você escrever exatamente o mesmo algoritmo, será lento (será interpretado). Este é um exemplo básico: você tem muitos truques usando vetores e matrizes, para evitar loops interpretados e fazer com que as funções pré-compiladas façam todo o trabalho.

Portanto, tenha muito cuidado. Após suas primeiras tentativas, você certamente sentirá nojo de R, porque o achará lento, com uma sintaxe estranha etc. Quando você o souber, pode ser uma ferramenta muito eficiente. Você pode até finalizar o script de seus métodos em R como uma fase preliminar da codificação C / C ++. O estágio final será aprender a API do R para criar funções pré-compiladas e você será um assistente do R :)

Elvis
fonte
2

A manipulação de matrizes na memória é algo importante para o SAS, aparentemente. Não conheço os detalhes específicos sobre R, mas suponho que R opere na memória por padrão, pois a memória que expande os pacotes para R, ff e bigmemory move os dados da memória para o disco. Eu tenho dicas para você, se você quiser melhorar a velocidade ou o uso da memória. Para melhorar a velocidade, primeiro você precisa usar R como pretendido, ou seja: vectorize seu código e use a compilação de código de bytes. (Além disso: evite o máximo possível as operações de cópia em memória.) Segundo, use o criador de código de código fornecido Rprof () para identificar patches lentos no seu código e, se necessário, reescreva-os em C ou C ++. Se você precisar de mais memória, poderá usar o argumento skip na função read.table () para ler seus dados um pedaço de cada vez e também pode usar um pacote como o RMySQL, que adiciona utilitários de manipulação de banco de dados ao R. Se você precisar de mais memória e puder reduzir a velocidade concomitantemente, poderá usar o pacote de neve para executar o R ​​em paralelo. (Você pode encontrar detalhes sobre isso, e muito mais, no livro "The Art of R Programming", de Norman Matloff, publicado no final do ano passado. Detalhes sobre os pacotes mencionados aqui podem ser encontrados on-line.)

Jean-Victor Côté
fonte