2015-12-19 9 views
20

vidi:Qual è il vero significato di "Tutto ciò che esiste è un oggetto" in R?

“Per capire i calcoli di R, due parole d'ordine sono utili:

• Tutto ciò che esiste è un oggetto.
• Tutto ciò che accade è una chiamata di funzione "

- John Chambers

Ma ho appena scoperto:.

a <- 2 
is.object(a) 
# FALSE 

In realtà, se una variabile è un tipo di base puro, è risultato is.object() sarebbe FALSE, quindi non dovrebbe essere un oggetto

Quindi qual è il vero significato di "Tutto ciò che esiste è un oggetto" in R?

+0

Per molti linguaggi di programmazione, suppongo che solo si può chiamare 'x' è una variabile , non un oggetto, se 'x' ha solo un valore. –

risposta

19

La funzione is.object sembra solo se l'oggetto ha un attributo "class". Quindi non ha lo stesso significato dello slogan.

Per esempio:

x <- 1 
attributes(x) # it does not have a class attribute 
NULL 
is.object(x) 
[1] FALSE 
class(x) <- "my_class" 
attributes(x) # now it has a class attribute 
$class 
[1] "my_class" 
is.object(x) 
[1] TRUE 

Ora, cercando di rispondere alla tua domanda reale, circa lo slogan, questo è come vorrei metterlo. Tutto ciò che esiste in R è un oggetto nel senso che è un tipo di struttura dati che può essere manipolata. Penso che questo sia meglio compreso con le funzioni e le espressioni, che di solito non vengono considerate come dati.

Prendendo un preventivo da Chambers (2008):

Il calcolo centrale in R è una chiamata di funzione, definito dall'oggetto funzione stessa e gli oggetti che vengono forniti come argomenti. Nel modello di programmazione funzionale, il risultato è definito da da un altro oggetto, il valore della chiamata. Da qui il tradizionale motto del linguaggio S: tutto è un oggetto - gli argomenti, il valore, e in effetti la funzione e la chiamata stessa: tutti questi sono definiti come oggetti . Pensa agli oggetti come raccolte di dati di tutti i tipi. I dati contenuti e il modo in cui i dati sono organizzati dipendono dalla classe da cui è stato generato l'oggetto.

Prendere questa espressione ad esempio mean(rnorm(100), trim = 0.9). Finché non viene valutato, è un oggetto molto simile a qualsiasi altro. Quindi puoi cambiare i suoi elementi proprio come faresti con una lista.Per esempio:

call <- substitute(mean(rnorm(100), trim = 0.9)) 
call[[2]] <- substitute(rt(100,2)) 
call 
mean(rt(100, 2), trim = 0.9) 

o fare una funzione, come rnorm:

rnorm 
function (n, mean = 0, sd = 1) 
.Call(C_rnorm, n, mean, sd) 
<environment: namespace:stats> 

È possibile modificare i suoi argomenti di default, proprio come un semplice oggetto, come una lista, anche:

formals(rnorm)[2] <- 100 
rnorm 
function (n, mean = 100, sd = 1) 
.Call(C_rnorm, n, mean, sd) 
<environment: namespace:stats> 

Riprendendo ancora una volta da Chambers (2008):

Il concetto chiave è che le espressioni per la valutazione sono esse stesse oggetti; nel tradizionale motto del linguaggio S, tutto è un oggetto . La valutazione consiste nel prendere l'oggetto che rappresenta un'espressione e restituire l'oggetto che è il valore di tale espressione .

Tornando al nostro esempio di chiamata, lo call è un oggetto che rappresenta un altro oggetto. Quando viene valutato, diventa quell'altro oggetto, che in questo caso è il vettore numerico con un numero: -0.008138572.

set.seed(1) 
eval(call) 
[1] -0.008138572 

E che ci avrebbe portato al secondo slogan, che non ha citato, ma di solito viene fornito insieme con la prima: "Tutto ciò che accade è una chiamata di funzione".

Riprendendo da Chambers (2008), egli in realtà si qualifica questa affermazione un po ':

Quasi tutto ciò che accade nei risultati di ricerca da una chiamata di funzione. Pertanto, la programmazione di base si concentra sulla creazione e sulla raffinazione delle funzioni .

Quindi, ciò significa che quasi tutte le trasformazioni di dati che si verificano in R sono chiamate di funzione. Anche una cosa semplice, come una parentesi, è una funzione in R.

Quindi, prendendo la parentesi come un esempio, si può effettivamente ridefinirlo a fare le cose in questo modo:

che non è una buona idea, ma illustra il punto. Quindi immagino che questo sia come vorrei riassumerlo: tutto ciò che esiste in R è un oggetto perché sono dati che possono essere manipolati. E (quasi) tutto ciò che accade è una chiamata di funzione, che è una valutazione di questo oggetto che ti dà un altro oggetto.

+0

buona comprensione, fammi pensare. –

+0

Ciao @Carlos, suppongo che ora conosca la definizione di "oggetto" in R. Come hai detto, un oggetto è solo una specie di struttura dati che può essere manipolata. Questo è abbastanza diverso con altri linguaggi, come Python, Ruby, Java. Suppongo che sia perché R ha un sistema di classi differenti. –

+0

e is.object (x) è FALSE, significa solo che questo oggetto non ha ancora attributi. Questo è tutto. E in realtà, non credo che R abbia un sistema di classe reale, e R non ne ha bisogno. Dal momento che è un linguaggio funzionale, tutti i sistemi di classe sono solo zucchero sintattico e un po 'brutti. –

9

Amo questa citazione.

In un'altra (qui di inedito) scrittura-up, l'autore prosegue con

R ha una struttura interna uniforme per rappresentare tutti gli oggetti. Il processo di valutazione esclude tale struttura, in una forma semplice che è essenzialmente composta da chiamate di funzione, con oggetti come argomenti e un oggetto come il valore . Comprendere il ruolo centrale degli oggetti e delle funzioni in R rende l'uso del software più efficace per qualsiasi applicazione stimolante, anche quelli in cui l'estensione di R non è l'obiettivo.

ma poi spende diverse centinaia di pagine espandendosi su di esso. Sarà una buona lettura una volta terminata.

7

oggetti Per x siano un oggetto significa che ha una classe così class(x) restituisce una classe per ogni oggetto. Anche le funzioni hanno una classe come fanno gli ambienti e gli altri oggetti non si potrebbe aspettare:

class(sin) 
## [1] "function" 

class(.GlobalEnv) 
## [1] "environment" 

non vorrei prestare troppa attenzione a is.object. is.object(x) ha un significato leggermente diverso da quello che stiamo usando qui - restituisce VERO se x ha un nome di classe memorizzato internamente insieme al suo valore. Se la classe è memorizzata, allora class(x) restituisce il valore memorizzato e, in caso contrario, class(x) lo calcolerà dal tipo. Dal punto di vista concettuale non importa come la classe sia rappresentata internamente (archiviata o computerd) - ciò che importa è che in entrambi i casi x è ancora un oggetto e ha ancora una classe.

Funzioni Il fatto che tutto il calcolo avvenga tramite le funzioni si riferisce al fatto che anche le cose che non ci si aspetta siano funzioni sono in realtà funzioni. Per esempio quando scriviamo:

{ 1; 2 } 
## [1] 2 

if (pi > 0) 2 else 3 
## [1] 2 

1+2 
## [1] 3 

ci sono in realtà facendo invocazioni delle funzioni {, if e +:

`{`(1, 2) 
## [1] 2 

`if`(pi > 0, 2, 3) 
## [1] 2 

`+`(1, 2) 
## [1] 3