Sou iniciante em R e estou bastante confuso com o uso de variáveis locais e globais em R.
Li algumas postagens na internet que dizem se eu uso =
ou <-
atribuirei a variável no ambiente atual e, com <<-
isso, posso acessar uma variável global quando dentro de uma função.
No entanto, como eu lembro em C ++, variáveis locais surgem sempre que você declara uma variável entre colchetes {}
, então, eu estou querendo saber se isso é o mesmo para R? Ou é apenas para funções em R que temos o conceito de variáveis locais.
Fiz um pequeno experimento, que parece sugerir que apenas colchetes não são suficientes. Estou entendendo algo errado?
{
x=matrix(1:10,2,5)
}
print(x[2,2])
[1] 4
globalenv(); globalenv() %>% parent.env; globalenv() %>% parent.env %>% parent.env
,…Error: could not find function "%>%"
,. Essa é outra forma de atribuição?require(magrittr)
. É uma maneira de aplicar funções à direita (x | f1 | f2 | f3
) em vez de à esquerda (f3( f2( f1( x ) ) )
).Respostas:
Variáveis declaradas dentro de uma função são locais para essa função. Por exemplo:
dá o seguinte erro:
Error: object 'bar' not found
.Se você deseja criar
bar
uma variável global, faça:Nesse caso,
bar
é acessível de fora da função.No entanto, diferentemente de C, C ++ ou de muitas outras linguagens, os colchetes não determinam o escopo das variáveis. Por exemplo, no seguinte trecho de código:
y
permanece acessível após aif-else
declaração.Como você bem diz, também é possível criar ambientes aninhados. Você pode dar uma olhada nesses dois links para entender como usá-los:
Aqui você tem um pequeno exemplo:
fonte
<-
faz atribuição no ambiente atual.Quando você está dentro de uma função, R cria um novo ambiente para você. Por padrão, inclui tudo, desde o ambiente em que foi criado, para que você possa usar essas variáveis também, mas qualquer coisa nova que você criar não será gravada no ambiente global.
Na maioria dos casos
<<-
, atribuirá a variáveis que já estão no ambiente global ou criará uma variável no ambiente global, mesmo se você estiver dentro de uma função. No entanto, não é tão simples assim. O que ele faz é verificar no ambiente pai uma variável com o nome de interesse. Se ele não o encontrar no ambiente pai, ele será direcionado ao pai do ambiente pai (no momento em que a função foi criada) e procurado lá. Ele continua ascendendo ao ambiente global e, se não for encontrado no ambiente global, atribuirá a variável ao ambiente global.Isso pode ilustrar o que está acontecendo.
A primeira vez que imprimimos barra, ainda não ligamos,
foo
portanto ainda deve ser global - isso faz sentido. Na segunda vez em que imprimimos,foo
antes de chamarbaz
, o valor "in foo" faz sentido. A seguir, é onde vemos o que<<-
realmente está fazendo. O próximo valor impresso é "in baz - before << -", mesmo que a instrução print venha após o<<-
. Isso ocorre porque<<-
não parece no ambiente atual (a menos que você esteja no ambiente global, caso em que<<-
atua como<-
). Portanto, dentro dobaz
valor da barra permanece como "in baz - before << -". Depois que chamamosbaz
a cópia da barra dentro defoo
é alterada para "in baz", mas como podemos ver, o globalbar
permanece inalterado.bar
que é definido dentro defoo
está no ambiente pai quando criamos,baz
portanto esta é a primeira cópia dobar
que<<-
vê e, portanto, a cópia à qual ele atribui. Portanto,<<-
não é apenas atribuir diretamente ao ambiente global.<<-
é complicado e eu não recomendaria usá-lo se você puder evitá-lo. Se você realmente deseja atribuir ao ambiente global, pode usar a função de atribuição e informar explicitamente que deseja atribuir globalmente.Agora eu mudo
<<-
para uma declaração de atribuição e podemos ver qual efeito isso tem:Portanto, nas duas vezes em que imprimimos a barra dentro do
foo
valor, "in foo", mesmo após a chamadabaz
. Isso ocorre porqueassign
nunca consideramos a cópia debar
dentro de foo porque dissemos exatamente onde procurar. No entanto, desta vez, o valor da barra no ambiente global foi alterado porque atribuímos explicitamente lá.Agora você também perguntou sobre a criação de variáveis locais e pode fazer isso com bastante facilidade, sem criar uma função ... Só precisamos usar a
local
função.fonte
Um pouco mais na mesma linha
irá imprimir "1"
Irá imprimir "20"
fonte