Oggetti non atomici in R

Alla fine di questa puntata…

  • dovreste riuscire a mettere insieme un insieme di comandi in uno script
  • dovreste riuscire a “personalizzare” l’ingresso in R e l’uscita da R
  • dovreste conoscere la sintassi per la creazione di una semplice funzione
  • dovreste conoscere i due tipi principali di oggetti non atomici
  • dovreste riuscire a dare un nome alle cose… pardon, agli oggetti

e molto probabilmente…

  • potreste iniziare a rispondere alla domanda “ma fa veramente al caso mio?”

Che emozione: il primo script…

Un semplice esempio di un file script: salviamo le seguenti istruzioni nel file provaScript.R nella directory corrente:

matrice1 <- matrix(nrow=5, ncol=2, data=1:10) #creo una matrice
print(matrice1)                               #e la stampo a video
(matrice2 <- matrix(12:1, 1, nrow=6, ncol=2)) #creo una seconda matrice e la stampo a vide
vettoreLunghezza10 <- 1:10                    #creo due vettori
vettoreLunghezza12 <- 12:1                    #
ls()                                          #stampo a video il contenuto del workspace

Per richiamare un file script si può usare la funzione source:

source("provaScript.R")

Ma perchè non usare l’interfaccia di RStudio?

Si riparte: due particolari contenitori…

Vediamo cosa abbiamo disponibile sul workspace:

load("introduzioneR.RData")
ls()
 [1] "altroVettoreCaratteri" "array3d"               "arrayDouble"          
 [4] "matrice1"              "matrice2"              "matriceCaratteri"     
 [7] "matriceDouble"         "matriceInteri"         "scalare"              
[10] "varAppoggio"           "vettoreCaratteri"      "vettoreDouble"        
[13] "vettoreIntero"         "vettoreLunghezza10"    "vettoreLunghezza12"   
[16] "vettoreLunghezza2"     "vettoreLunghezza3"    

Un oggetto non atomico in grado di contenere oggetti di struttura e con contenuto differente:

listaSenzaNomi <- list(scalare, vettoreLunghezza10, vettoreCaratteri, matrice1)
is.atomic(listaSenzaNomi)
[1] FALSE
listaSenzaNomi
[[1]]
[1] 1

[[2]]
 [1]  1  2  3  4  5  6  7  8  9 10

[[3]]
[1] "a"  "b"  "cc"

[[4]]
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6
[4,]    7    8
[5,]    9   10

Possiamo anche decidere di assegnare un nome a ciascun componente della lista da utilizzare in seguito in alternativa alla posizione per richiamare gli elementi:

listaNomi <- list(scal=scalare, vettore=vettoreLunghezza10, vetCar=vettoreCaratteri, mat=matrice1)
listaNomi
$scal
[1] 1

$vettore
 [1]  1  2  3  4  5  6  7  8  9 10

$vetCar
[1] "a"  "b"  "cc"

$mat
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6
[4,]    7    8
[5,]    9   10

Qualche informazione tecnica sulla lista

c(mode(listaNomi), class(listaNomi), typeof(listaNomi))
[1] "list" "list" "list"

Un tipo particolare di lista: la tabella dati (o dataframe)

dfNomi <- data.frame(var1=vettoreCaratteri, var2=vettoreLunghezza3)
is.atomic(dfNomi)
[1] FALSE
dfNomi
  var1 var2
1    a    1
2    b    2
3   cc    3

Qualche informazione tecnica sul dataframe (da confrontare con quelle della lista)

c(mode(dfNomi), class(dfNomi), typeof(dfNomi))
[1] "list"       "data.frame" "list"      

NOTA: già visto in precedenza, ma forse adesso è più chiaro Per la funzione generica print esiste una funzione diversa per ciascuno dei tipi. In particolare dovreste vedere, tra le altre, una funzione che regola la stampa di una lista e di un dataframe

methods(print)
  [1] print.acf*                                          
  [2] print.activeConcordance*                            
  [3] print.AES*                                          
  [4] print.anova*                                        
  [5] print.aov*                                          
  [6] print.aovlist*                                      
  [7] print.ar*                                           
  [8] print.Arima*                                        
  [9] print.arima0*                                       
 [10] print.AsIs                                          
 [11] print.aspell*                                       
 [12] print.aspell_inspect_context*                       
 [13] print.bibentry*                                     
 [14] print.Bibtex*                                       
 [15] print.browseVignettes*                              
 [16] print.by                                            
 [17] print.changedFiles*                                 
 [18] print.check_bogus_return*                           
 [19] print.check_code_usage_in_package*                  
 [20] print.check_compiled_code*                          
 [21] print.check_demo_index*                             
 [22] print.check_depdef*                                 
 [23] print.check_details*                                
 [24] print.check_details_changes*                        
 [25] print.check_doi_db*                                 
 [26] print.check_dotInternal*                            
 [27] print.check_make_vars*                              
 [28] print.check_nonAPI_calls*                           
 [29] print.check_package_code_assign_to_globalenv*       
 [30] print.check_package_code_attach*                    
 [31] print.check_package_code_data_into_globalenv*       
 [32] print.check_package_code_startup_functions*         
 [33] print.check_package_code_syntax*                    
 [34] print.check_package_code_unload_functions*          
 [35] print.check_package_compact_datasets*               
 [36] print.check_package_CRAN_incoming*                  
 [37] print.check_package_datalist*                       
 [38] print.check_package_datasets*                       
 [39] print.check_package_depends*                        
 [40] print.check_package_description*                    
 [41] print.check_package_description_encoding*           
 [42] print.check_package_license*                        
 [43] print.check_packages_in_dir*                        
 [44] print.check_packages_used*                          
 [45] print.check_po_files*                               
 [46] print.check_pragmas*                                
 [47] print.check_Rd_line_widths*                         
 [48] print.check_Rd_metadata*                            
 [49] print.check_Rd_xrefs*                               
 [50] print.check_RegSym_calls*                           
 [51] print.check_S3_methods_needing_delayed_registration*
 [52] print.check_so_symbols*                             
 [53] print.check_T_and_F*                                
 [54] print.check_url_db*                                 
 [55] print.check_vignette_index*                         
 [56] print.checkDocFiles*                                
 [57] print.checkDocStyle*                                
 [58] print.checkFF*                                      
 [59] print.checkRd*                                      
 [60] print.checkRdContents*                              
 [61] print.checkReplaceFuns*                             
 [62] print.checkS3methods*                               
 [63] print.checkTnF*                                     
 [64] print.checkVignettes*                               
 [65] print.citation*                                     
 [66] print.cli_ansi_html_style*                          
 [67] print.cli_ansi_string*                              
 [68] print.cli_ansi_style*                               
 [69] print.cli_boxx*                                     
 [70] print.cli_diff_chr*                                 
 [71] print.cli_doc*                                      
 [72] print.cli_progress_demo*                            
 [73] print.cli_rule*                                     
 [74] print.cli_sitrep*                                   
 [75] print.cli_spark*                                    
 [76] print.cli_spinner*                                  
 [77] print.cli_tree*                                     
 [78] print.codoc*                                        
 [79] print.codocClasses*                                 
 [80] print.codocData*                                    
 [81] print.colorConverter*                               
 [82] print.compactPDF*                                   
 [83] print.condition                                     
 [84] print.connection                                    
 [85] print.CRAN_package_reverse_dependencies_and_views*  
 [86] print.data.frame                                    
 [87] print.Date                                          
 [88] print.default                                       
 [89] print.dendrogram*                                   
 [90] print.density*                                      
 [91] print.difftime                                      
 [92] print.dist*                                         
 [93] print.Dlist                                         
 [94] print.DLLInfo                                       
 [95] print.DLLInfoList                                   
 [96] print.DLLRegisteredRoutines                         
 [97] print.document_context*                             
 [98] print.document_position*                            
 [99] print.document_range*                               
[100] print.document_selection*                           
[101] print.dummy_coef*                                   
[102] print.dummy_coef_list*                              
[103] print.ecdf*                                         
[104] print.eigen                                         
[105] print.factanal*                                     
[106] print.factor                                        
[107] print.family*                                       
[108] print.fileSnapshot*                                 
[109] print.findLineNumResult*                            
[110] print.formula*                                      
[111] print.ftable*                                       
[112] print.function                                      
[113] print.getAnywhere*                                  
[114] print.glm*                                          
[115] print.hashtab*                                      
[116] print.hclust*                                       
[117] print.help_files_with_topic*                        
[118] print.hexmode                                       
[119] print.HoltWinters*                                  
[120] print.hsearch*                                      
[121] print.hsearch_db*                                   
[122] print.htest*                                        
[123] print.html*                                         
[124] print.html_dependency*                              
[125] print.htmltools.selector*                           
[126] print.htmltools.selector.list*                      
[127] print.htmlwidget*                                   
[128] print.infl*                                         
[129] print.integrate*                                    
[130] print.isoreg*                                       
[131] print.json*                                         
[132] print.key_missing*                                  
[133] print.kmeans*                                       
[134] print.knitr_kable*                                  
[135] print.Latex*                                        
[136] print.LaTeX*                                        
[137] print.libraryIQR                                    
[138] print.listof                                        
[139] print.lm*                                           
[140] print.loadings*                                     
[141] print.loess*                                        
[142] print.logLik*                                       
[143] print.ls_str*                                       
[144] print.medpolish*                                    
[145] print.MethodsFunction*                              
[146] print.mtable*                                       
[147] print.NativeRoutineList                             
[148] print.news_db*                                      
[149] print.nls*                                          
[150] print.noquote                                       
[151] print.numeric_version                               
[152] print.object_size*                                  
[153] print.octmode                                       
[154] print.packageDescription*                           
[155] print.packageInfo                                   
[156] print.packageIQR*                                   
[157] print.packageStatus*                                
[158] print.paged_df*                                     
[159] print.pairwise.htest*                               
[160] print.person*                                       
[161] print.POSIXct                                       
[162] print.POSIXlt                                       
[163] print.power.htest*                                  
[164] print.ppr*                                          
[165] print.prcomp*                                       
[166] print.princomp*                                     
[167] print.proc_time                                     
[168] print.quosure*                                      
[169] print.quosures*                                     
[170] print.raster*                                       
[171] print.Rconcordance*                                 
[172] print.Rd*                                           
[173] print.recordedplot*                                 
[174] print.restart                                       
[175] print.RGBcolorConverter*                            
[176] print.RGlyphFont*                                   
[177] print.rlang_box_done*                               
[178] print.rlang_box_splice*                             
[179] print.rlang_data_pronoun*                           
[180] print.rlang_dict*                                   
[181] print.rlang_dyn_array*                              
[182] print.rlang_envs*                                   
[183] print.rlang_error*                                  
[184] print.rlang_fake_data_pronoun*                      
[185] print.rlang_lambda_function*                        
[186] print.rlang_message*                                
[187] print.rlang_trace*                                  
[188] print.rlang_warning*                                
[189] print.rlang_zap*                                    
[190] print.rlang:::list_of_conditions*                   
[191] print.rle                                           
[192] print.rlib_bytes*                                   
[193] print.rlib_error_3_0*                               
[194] print.rlib_trace_3_0*                               
[195] print.roman*                                        
[196] print.scalar*                                       
[197] print.sessionInfo*                                  
[198] print.shiny.tag*                                    
[199] print.shiny.tag.env*                                
[200] print.shiny.tag.list*                               
[201] print.shiny.tag.query*                              
[202] print.simple.list                                   
[203] print.smooth.spline*                                
[204] print.socket*                                       
[205] print.srcfile                                       
[206] print.srcref                                        
[207] print.stepfun*                                      
[208] print.stl*                                          
[209] print.StructTS*                                     
[210] print.subdir_tests*                                 
[211] print.summarize_CRAN_check_status*                  
[212] print.summary.aov*                                  
[213] print.summary.aovlist*                              
[214] print.summary.ecdf*                                 
[215] print.summary.glm*                                  
[216] print.summary.lm*                                   
[217] print.summary.loess*                                
[218] print.summary.manova*                               
[219] print.summary.nls*                                  
[220] print.summary.packageStatus*                        
[221] print.summary.ppr*                                  
[222] print.summary.prcomp*                               
[223] print.summary.princomp*                             
[224] print.summary.table                                 
[225] print.summary.warnings                              
[226] print.summaryDefault                                
[227] print.suppress_viewer*                              
[228] print.table                                         
[229] print.tables_aov*                                   
[230] print.terms*                                        
[231] print.ts*                                           
[232] print.tskernel*                                     
[233] print.TukeyHSD*                                     
[234] print.tukeyline*                                    
[235] print.tukeysmooth*                                  
[236] print.undoc*                                        
[237] print.vignette*                                     
[238] print.warnings                                      
[239] print.xfun_raw_string*                              
[240] print.xfun_record_results*                          
[241] print.xfun_rename_seq*                              
[242] print.xfun_strict_list*                             
[243] print.xgettext*                                     
[244] print.xngettext*                                    
[245] print.xtabs*                                        
see '?methods' for accessing help and source code

La regola del riciclaggio viene applicato anche nel caso della creazione del dataframe:

data.frame(scalare, vettoreLunghezza10)
   scalare vettoreLunghezza10
1        1                  1
2        1                  2
3        1                  3
4        1                  4
5        1                  5
6        1                  6
7        1                  7
8        1                  8
9        1                  9
10       1                 10
data.frame(vettoreLunghezza2, vettoreLunghezza10)
   vettoreLunghezza2 vettoreLunghezza10
1                  2                  1
2                  3                  2
3                  2                  3
4                  3                  4
5                  2                  5
6                  3                  6
7                  2                  7
8                  3                  8
9                  2                  9
10                 3                 10

Attenzione: non nel caso in cui il numero di elementi dell’oggetto di lunghezza più piccolo non è un sottomultiplo esatto del numero di elementi dell’oggetto di lunghezza più grande

data.frame(vettoreLunghezza3, vettoreLunghezza10)
cbind(vettoreLunghezza3, vettoreLunghezza10)

Fatta (nota) la legge trovato l’inganno: un piccolo sotterfugio per aggirare l’ostacolo

as.data.frame(cbind(vettoreLunghezza3, vettoreLunghezza10))
Warning in cbind(vettoreLunghezza3, vettoreLunghezza10): number of rows of
result is not a multiple of vector length (arg 1)
   vettoreLunghezza3 vettoreLunghezza10
1                  1                  1
2                  2                  2
3                  3                  3
4                  1                  4
5                  2                  5
6                  3                  6
7                  1                  7
8                  2                  8
9                  3                  9
10                 1                 10

Sintassi equivalente:

data.frame(cbind(vettoreLunghezza3, vettoreLunghezza10))
Warning in cbind(vettoreLunghezza3, vettoreLunghezza10): number of rows of
result is not a multiple of vector length (arg 1)
   vettoreLunghezza3 vettoreLunghezza10
1                  1                  1
2                  2                  2
3                  3                  3
4                  1                  4
5                  2                  5
6                  3                  6
7                  1                  7
8                  2                  8
9                  3                  9
10                 1                 10

Attenzione alla conversione dei tipi in queste operazioni

data.frame(vettoreLunghezza3, vettoreCaratteri)
  vettoreLunghezza3 vettoreCaratteri
1                 1                a
2                 2                b
3                 3               cc

Solo apparentemente la creazione del data.frame avviene conservando i tipi reali degli oggetti (entrambi vengono gestiti come fattori - vedi più avanti)

data.frame(cbind(vettoreLunghezza3, vettoreCaratteri))
  vettoreLunghezza3 vettoreCaratteri
1                 1                a
2                 2                b
3                 3               cc

Per convincersene basta guardare l’output del comando interno:

cbind(vettoreLunghezza3, vettoreCaratteri)
     vettoreLunghezza3 vettoreCaratteri
[1,] "1"               "a"             
[2,] "2"               "b"             
[3,] "3"               "cc"            

Una controprova: cambiamo il parametro che per default converte le variabili di tipo stringa in fattori nella funzione data.frame:

df1 <- data.frame(vettoreLunghezza3, vettoreCaratteri, stringsAsFactors=FALSE)
df1
  vettoreLunghezza3 vettoreCaratteri
1                 1                a
2                 2                b
3                 3               cc
df2 <- data.frame(cbind(vettoreLunghezza3, vettoreCaratteri), stringsAsFactors=FALSE)
df2
  vettoreLunghezza3 vettoreCaratteri
1                 1                a
2                 2                b
3                 3               cc

Cosa c’è nel dataframe? La stampa dell’oggetto potrebbe ingannare. Per accedere ad una colonna si può usare il $ e il nome della colonna (dopo per ulteriori dettagli):

df1$vettoreLunghezza3
[1] 1 2 3
df1$vettoreCaratteri
[1] "a"  "b"  "cc"
df2$vettoreLunghezza3
[1] "1" "2" "3"
df2$vettoreCaratteri
[1] "a"  "b"  "cc"

Un dataframe è un sotto-tipo di una lista (con un vincolo: lunghezza uguale per tutti i componenti della lista)

dfNomi
  var1 var2
1    a    1
2    b    2
3   cc    3
is.list(dfNomi)
[1] TRUE
is.data.frame(dfNomi)
[1] TRUE
listaNomi
$scal
[1] 1

$vettore
 [1]  1  2  3  4  5  6  7  8  9 10

$vetCar
[1] "a"  "b"  "cc"

$mat
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6
[4,]    7    8
[5,]    9   10
is.list(listaNomi)
[1] TRUE
is.data.frame(listaNomi)
[1] FALSE

Non sei ancora convinto?

c(mode(dfNomi), class(dfNomi), typeof(dfNomi))
[1] "list"       "data.frame" "list"      

Da un contenitore all’altro…

A volte la conversione è lineare:

dfNomi
  var1 var2
1    a    1
2    b    2
3   cc    3
as.list(dfNomi)
$var1
[1] "a"  "b"  "cc"

$var2
[1] 1 2 3

Altre volte è impossibile:

listaNomi
as.data.frame(listaNomi)

Torniamo al punto di partenza:

as.data.frame(as.list(dfNomi))
  var1 var2
1    a    1
2    b    2
3   cc    3

In alcuni casi si può rinunciare alla struttura e cercare di preservare il contenuto degli oggetti, naturalmente con qualche necessario compromesso

unlist(listaNomi)
     scal  vettore1  vettore2  vettore3  vettore4  vettore5  vettore6  vettore7 
      "1"       "1"       "2"       "3"       "4"       "5"       "6"       "7" 
 vettore8  vettore9 vettore10   vetCar1   vetCar2   vetCar3      mat1      mat2 
      "8"       "9"      "10"       "a"       "b"      "cc"       "1"       "3" 
     mat3      mat4      mat5      mat6      mat7      mat8      mat9     mat10 
      "5"       "7"       "9"       "2"       "4"       "6"       "8"      "10" 
unlist(dfNomi)
var11 var12 var13 var21 var22 var23 
  "a"   "b"  "cc"   "1"   "2"   "3" 

Un altro attributo particolare: i nomi

Gli oggetti, oltre a mode e dim, hanno anche un attributo che regola i nomi dei singoli elementi:

names(vettoreLunghezza2)
NULL
names(vettoreLunghezza2) <- c("primo","secondo")
vettoreLunghezza2
  primo secondo 
      2       3 

Riecco la funzione attributes:

attributes(vettoreLunghezza2)
$names
[1] "primo"   "secondo"

La regola del riciclaggio non vale per i nomi:

names(vettoreLunghezza10) <- c("lun","mar","mer","gio","ven")
vettoreLunghezza10
 lun  mar  mer  gio  ven <NA> <NA> <NA> <NA> <NA> 
   1    2    3    4    5    6    7    8    9   10 

La scelta dei nomi tocca a noi (R non vuole responsabilità):

names(vettoreLunghezza10) <- rep(c("lun","mar","mer","gio","ven"), 2)
vettoreLunghezza10
lun mar mer gio ven lun mar mer gio ven 
  1   2   3   4   5   6   7   8   9  10 

Si possono fissare sia nomi per i singoli elementi:

matrice1
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6
[4,]    7    8
[5,]    9   10
names(matrice1) <- letters[1:10]
matrice1
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6
[4,]    7    8
[5,]    9   10
attr(,"names")
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"

che nomi associati alle dimensioni (laddove queste siano presenti):

dimnames(matrice1)
NULL

Una parentesi: la funzione paste può essere usata per creare al volo le etichette:

paste("prova", 1:10)
 [1] "prova 1"  "prova 2"  "prova 3"  "prova 4"  "prova 5"  "prova 6" 
 [7] "prova 7"  "prova 8"  "prova 9"  "prova 10"
paste("prova", 1:10, sep="")
 [1] "prova1"  "prova2"  "prova3"  "prova4"  "prova5"  "prova6"  "prova7" 
 [8] "prova8"  "prova9"  "prova10"
#nel caso della matrice potremmo usare
paste("riga", 1:nrow(matrice1), sep="")
[1] "riga1" "riga2" "riga3" "riga4" "riga5"

E’ possibile assegnare dei nomi a una sola delle dimensioni:

dimnames(matrice1) <- list(paste("riga", 1:nrow(matrice1), sep=""), NULL)
matrice1
      [,1] [,2]
riga1    1    2
riga2    3    4
riga3    5    6
riga4    7    8
riga5    9   10
attr(,"names")
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
rownames(matrice1)
[1] "riga1" "riga2" "riga3" "riga4" "riga5"
colnames(matrice1)
NULL

Si possono assegnare i nomi anche ad entrambe le dimensioni:

dimnames(matrice1) <- list(
                           paste("riga", 1:nrow(matrice1), sep=""),
                           paste("colonna", 1:ncol(matrice1), sep="")
                           )
matrice1
      colonna1 colonna2
riga1        1        2
riga2        3        4
riga3        5        6
riga4        7        8
riga5        9       10
attr(,"names")
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"

Dall’esempio è facile intuire come sia possibile anche sfruttare una funzione differente per i nomi di riga e per i nomi di colonna:

dimnames(matrice1) <- NULL
matrice1
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6
[4,]    7    8
[5,]    9   10
attr(,"names")
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
rownames(matrice1) <- paste("riga", 1:nrow(matrice1), sep="")
colnames(matrice1) <- paste("colonna", 1:ncol(matrice1), sep="")
matrice1
      colonna1 colonna2
riga1        1        2
riga2        3        4
riga3        5        6
riga4        7        8
riga5        9       10
attr(,"names")
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"

Una piccola nota sugli “attributi” di un oggetto

La funzione attributes permette di visualizzare gli attributi impostati:

attributes(matrice1)
$dim
[1] 5 2

$names
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"

$dimnames
$dimnames[[1]]
[1] "riga1" "riga2" "riga3" "riga4" "riga5"

$dimnames[[2]]
[1] "colonna1" "colonna2"

La funzione attr permette di accedere ad un singolo attributo di un oggetto usando il nome dell’attributo:

attr(matrice1,"dim")
[1] 5 2
attr(matrice1,"names")
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
attr(matrice1,"dimnames")
[[1]]
[1] "riga1" "riga2" "riga3" "riga4" "riga5"

[[2]]
[1] "colonna1" "colonna2"

Ritorniamo ai nomi delle cose…

Anche nel caso dell’array3d è possibile impostare i nomi per i singoli elementi

array3d
, , 1

     [,1] [,2] [,3]
[1,]    1    5    9
[2,]    2    6   10
[3,]    3    7   11
[4,]    4    8   12

, , 2

     [,1] [,2] [,3]
[1,]   13   17   21
[2,]   14   18   22
[3,]   15   19   23
[4,]   16   20   24
names(array3d)
NULL
names(array3d) <- letters[1:length(array3d)]
array3d
, , 1

     [,1] [,2] [,3]
[1,]    1    5    9
[2,]    2    6   10
[3,]    3    7   11
[4,]    4    8   12

, , 2

     [,1] [,2] [,3]
[1,]   13   17   21
[2,]   14   18   22
[3,]   15   19   23
[4,]   16   20   24

attr(,"names")
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
[20] "t" "u" "v" "w" "x"

e i nomi per ciascuna delle dimensioni

array3d
, , 1

     [,1] [,2] [,3]
[1,]    1    5    9
[2,]    2    6   10
[3,]    3    7   11
[4,]    4    8   12

, , 2

     [,1] [,2] [,3]
[1,]   13   17   21
[2,]   14   18   22
[3,]   15   19   23
[4,]   16   20   24

attr(,"names")
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
[20] "t" "u" "v" "w" "x"
dimnames(array3d)
NULL
dimnames(array3d) <-
  list(paste("riga", 1:dim(array3d)[1], sep=""),
                          paste("colonna", 1:dim(array3d)[2], sep=""),
                          paste("strato", 1:dim(array3d)[3],sep=""))
array3d
, , strato1

      colonna1 colonna2 colonna3
riga1        1        5        9
riga2        2        6       10
riga3        3        7       11
riga4        4        8       12

, , strato2

      colonna1 colonna2 colonna3
riga1       13       17       21
riga2       14       18       22
riga3       15       19       23
riga4       16       20       24

attr(,"names")
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
[20] "t" "u" "v" "w" "x"
attributes(array3d)
$dim
[1] 4 3 2

$names
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
[20] "t" "u" "v" "w" "x"

$dimnames
$dimnames[[1]]
[1] "riga1" "riga2" "riga3" "riga4"

$dimnames[[2]]
[1] "colonna1" "colonna2" "colonna3"

$dimnames[[3]]
[1] "strato1" "strato2"

Nel caso delle liste i nomi dei singoli elementi sono quelli attribuiti esplicitamente in fase di creazione della lista:

names(listaSenzaNomi)
NULL
names(listaNomi)
[1] "scal"    "vettore" "vetCar"  "mat"    

E’ possibile assegnare dei nomi agli elementi della lista anche dopo la creazione:

names(listaSenzaNomi) <- letters[1:4]
listaSenzaNomi
$a
[1] 1

$b
 [1]  1  2  3  4  5  6  7  8  9 10

$c
[1] "a"  "b"  "cc"

$d
     [,1] [,2]
[1,]    1    2
[2,]    3    4
[3,]    5    6
[4,]    7    8
[5,]    9   10

Anche nel caso della lista la funzione attributes permette di accedere agli attributi impostati per l’oggetto

attributes(listaSenzaNomi)
$names
[1] "a" "b" "c" "d"

Se si usa la funzione attributes per il dataframe si nota che esistono due tipi di nomi associati: - names indica i nomi degli elementi del dataframe (ovvero delle due colonne della tabella) - row.names indica i nomi di riga che, se non esplicitamente definiti (come nel nostro caso) sono rappresentati da un numero sequenziale

NOTA: in quest’ultimo caso l’attributo è row.names

attributes(dfNomi)
$names
[1] "var1" "var2"

$class
[1] "data.frame"

$row.names
[1] 1 2 3

E’ possibile accedere ai nomi di riga del dataframe usando la funzione row.names e ai nomi di colonna usando la funzione names:

row.names(dfNomi)
[1] "1" "2" "3"
names(dfNomi)
[1] "var1" "var2"

E’ anche possibile usare le due funzioni rownames e colnames viste per l’accesso ai nomi di riga e colonna di una matrice (questo sempre nella logica che il dataframe può essere visto sia come una particolare lista con un vincolo aggiuntivo, che come una tabella con un vincolo in meno, ovvero come una tabellla “non atomica”)

rownames(dfNomi)
[1] "1" "2" "3"
colnames(dfNomi)
[1] "var1" "var2"

E’ infine possibile, in analogia a quanto visto per gli array, usare la funzione dimnames:

dimnames(dfNomi)
[[1]]
[1] "1" "2" "3"

[[2]]
[1] "var1" "var2"

<<Salva un pò, vai…>>

getwd()
[1] "/Users/domenico.vistocco/Downloads/rlab_website/labs"
save.image("introduzioneR_updated.RData")

Nota: un oggetto non atomico “moderno”…

Una struttura dati simile al data.frame è il tibble. Per dettagli si rimanda al manuale R for Data Science.