Índices nutricionales Del url http://world.openfoodfacts.org/data se puede descargar la tabla de datos FoodFacts.csv que contiene información sobre más de 65,000 productos alimentarios: en concreto, 156 variables, de las que 87 corresponden a contenidos nutricionales. La tabla completa ocupa más de 160 Mb (y además va aumentando casi cada día), así que para este ejercicio (en MiriadaX no nos dejan subir tablas de más de 5 Mb), a partir de esta tabla hemos construido una tabla con sólo algunos productos y las siguientes variables: • • • • • • • • • • • • • •
product_name: nombre del producto country: país donde se adquirió (cuando un producto ha sido adquirido en varios países, aparece una fila para cada país) continent: continente del país nutrition_grade_fr: escala nutricional francesa additives_n: número de aditivos main_category: categoría energy: calorías por 100 g del producto fat: grasa (en g) por 100 g del producto sugars: azúcares (en g) por 100 g del producto fiber: fibra (en g) por 100 g del producto proteins: proteínas (en g) por 100 g del producto sodium: sal (en g) por 100 g del producto alcohol: alcohol (en g) por 100 g del producto vitamin_b6: vitamina B6 (en g) por 100 g del producto
El resultado final es la tabla FoodFactsMooc.csv que encontraréis en el repositorio del curso (url https://miriadax.net/documents/28098821/74010125/FoodFactsMooc.csv/c1b38 463-6006-4a3b-b94a-a72d31d54831) A partir de esta tabla, vamos a estudiar algunos índices nutricionales por productos, por países y por continentes. a) Cargad la tabla de datos en un data frame "global" llamado DF_G; a continuación, cread un data frame para cada continente, y llamadlos DF_Europa, DF_Africa, DF_Asia, DF_AmericaN, DF_AmericaS, DF_Oceanía, respectivamente DF_G=read.csv("FoodFactsMooc.csv",header=TRUE) DF_Europa=DF_G[DF_G$continent=="Europe",] DF_Africa=DF_G[DF_G$continent=="Africa",] DF_Asia=DF_G[DF_G$continent=="Asia",] DF_AmericaN=DF_G[DF_G$continent=="North America",]
DF_AmericaS=DF_G[DF_G$continent=="South America",] DF_Oceania=DF_G[DF_G$continent=="Oceania",]
En algunos apartados necesitaremos eliminar repeticiones de productos de estos data frames. Un mismo producto puede aparecer varias veces en la tabla de partida, porque haya sido adquirido en diferentes países; si varias filas corresponden exactamente al mismo producto, sólo se diferencian en el país y, si corresponde, en el continente. Así que también tenéis que construir un data frame "global y sin repeticiones" DFU_G, que no contenga las variables correspondientes al país y el continente y donde cada producto aparezca una sola vez. ¿Cuántas repeticiones había en la tabla de datos original? DFU_G=unique(DF_G) length(DF_G$product_name)-length(DFU_G$product_name) ## [1] 609
En la tabla original había 609 repeticiones Asimismo, para cada continente, cread un data frame sin repeticiones (DFU_Europa, DFU_Africa, etc., que no contenga la variable correspondiente al país (pero dejad el continente, os va a ser ser útil dentro de un rato), donde cada producto aparezca una sola vez. DFU_Europa=unique(DF_Europa) DFU_Europa=DFU_Europa[,-2] DFU_Africa=unique(DF_Africa) DFU_Africa=DFU_Africa[,-2] DFU_Asia=unique(DF_Asia) DFU_Asia=DFU_Asia[,-2] DFU_AmericaN=unique(DF_AmericaN) DFU_AmericaN=DFU_AmericaN[,-2] DFU_AmericaS=unique(DF_AmericaS) DFU_AmericaS=DFU_AmericaS[,-2] DFU_Oceania=unique(DF_Oceania) DFU_Oceania=DFU_Oceania[,-2]
Finalmente, concatenad por filas los 6 data frames anteriores de la forma DFU_Continente en un único data frame DFU_Continentes. Este data frame contendrá productos repetidos, pero nunca dentro de un mismo continente. DFU_continente=rbind(DFU_Europa,DFU_Africa,DFU_Asia,DFU_AmericaN,DFU_ AmericaS,DFU_Oceania)
(Indicación: Si aplicáis la función unique a un dataframe, construís un nuevo dataframe eliminando las repeticiones de filas.) b) ¿Qué porcentajes de valores NA hay en las diferentes variables del data frame DFU_G? Sería conveniente que presentaseis esta información en forma de tabla. ¿Qué variables presentan un mayor porcentaje de valores NA? ¿Tenéis alguna explicación para ello?
additives_na=sum(is.na(DFU_G$additives_n))*100/length(DFU_G$additives_n ) energy_na=sum(is.na(DFU_G$energy))*100/length(DFU_G$additives_n) fat_na=sum(is.na(DFU_G$fat))*100/length(DFU_G$additives_n) sugars_na=sum(is.na(DFU_G$sugars))*100/length(DFU_G$additives_n) fiber_na=sum(is.na(DFU_G$fiber))*100/length(DFU_G$additives_n) proteins_na=sum(is.na(DFU_G$proteins))*100/length(DFU_G$additives_n) sodium_na=sum(is.na(DFU_G$sodium))*100/length(DFU_G$additives_n) alcohol_na=sum(is.na(DFU_G$alcohol))*100/length(DFU_G$additives_n) vitamin_b6_na=sum(is.na(DFU_G$vitamin_b6))*100/length(DFU_G$additives_ n) nas=c(additives_na,energy_na,fat_na,sugars_na,fiber_na,proteins_na,sodium_ na,alcohol_na,vitamin_b6_na) table.na=rbind(c("additivos","energía","grasas","azúcares","fibra","proteinas" ,"sodio","alcohol","vitaminaB6"),nas) table.na ## [,1] [,2] [,3] ## "additivos" "energía" "grasas" ## nas "7.28055301943394" "5.68410069127429" "5.73888091822095" ## [,4] [,5] [,6] ## "azúcares" "fibra" "proteinas" ## nas "15.609756097561" "41.6799269596974" "6.8657884439807" ## [,7] [,8] [,9] ## "sodio" "alcohol" "vitaminaB6" ## nas "15.0228250945611" "93.9402634668058" "98.171383852876"
El mayor porcentaje de NAs se encuentra en Vitamina B6 c) Calculad las correlaciones entre las variables numéricas del dataframe DFU_G (sus últimas 8 variables). Escoged la opción use que produzca menos NA. Opcionalmente, representad los valores absolutos de estas correlaciones mediante un diagrama de calor. A continuación: cor_DFU=cor(DFU_G[,7:14],use="pairwise.complete.obs") ## Warning in cor(DFU_G[, 7:14], use = "pairwise.complete.obs"): the standard ## deviation is zero cor_DFU ## energy fat sugars fiber proteins ## energy 1.00000000 0.786034123 0.35417773 0.28398754 0.23405129 ## fat 0.78603412 1.000000000 0.02459905 0.09569920 0.15292842 ## sugars 0.35417773 0.024599048 1.00000000 0.06374552 -0.23068248 ## fiber 0.28398754 0.095699199 0.06374552 1.00000000 0.22577468
## proteins 0.23405129 0.152928421 -0.23068248 0.22577468 1.00000000 ## sodium -0.02084474 0.005943899 -0.09505978 -0.02482017 0.08516568 ## alcohol -0.04613753 -0.088374917 -0.03601419 -0.06961277 -0.11744243 ## vitamin_b6 -0.01204493 -0.028964791 -0.04417694 -0.03250096 0.05524490 ## sodium alcohol vitamin_b6 ## energy -0.020844735 -0.04613753 -0.01204493 ## fat 0.005943899 -0.08837492 -0.02896479 ## sugars -0.095059781 -0.03601419 -0.04417694 ## fiber -0.024820173 -0.06961277 -0.03250096 ## proteins 0.085165677 -0.11744243 0.05524490 ## sodium 1.000000000 0.03110027 -0.01917713 ## alcohol 0.031100266 1.00000000 NA ## vitamin_b6 -0.019177134 NA 1.00000000
1.
Si lo habéis hecho bien, aparecerá una sola pareja de variables con correlación NA. ¿A qué se debe este valor?
la correlación entre alcohol y vitaminaB6 aparece como NA. Si miramos la tabla compuesta por las dos columnas alcohol y vitamineb6 temp=DFU_G[,13:14] na.omit(temp) ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
alcohol vitamin_b6 1087 0 0.000400 7250 0 0.002000 8571 0 0.000800 11434 0 0.000400 13549 0 0.002200 14401 0 0.000360 14558 0 0.001500 25654 0 0.000260 25741 0 0.000900 30009 0 0.001000 34849 0 0.001190 39076 0 0.000750 44976 0 0.000200 45326 0 0.001900 45886 0 0.000800 47851 0 0.000070 47852 0 0.000070 48346 0 0.000760 51479 0 0.000052 59604 0 0.000700 60259 0 0.002200 60558 0 0.000200
vemos que los únicos valores para los que existen datos de ambas variables juntas contienen valores de alcohol 0 y por tanto la corelación es NA. 2.
Determinad el par de variables numéricas diferentes con mayor correlación en valor absoluto, y dibujad su diagrama de dispersión incluyendo su recta de regresión.
medidas=names(DFU_G[,7:14]) n=length(medidas) indices=upper.tri(diag(n)) medida1=matrix(rep(medidas,times=n),nrow=n,byrow=FALSE)[indices] medida2=matrix(rep(medidas,times=n),nrow=n,byrow=TRUE)[indices] corrs=as.vector(cor(DFU_G[,7:14],use="pairwise.complete.obs"))[indices] ## Warning in cor(DFU_G[, 7:14], use = "pairwise.complete.obs"): the standard ## deviation is zero corrs.abs=abs(corrs) corrs.df=data.frame(medida1,medida2,corrs,corrs.abs) corrs.df_sort=corrs.df[order(corrs.df$corrs.abs,decreasing=TRUE),] corrs.df_sort ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
medida1 medida2 corrs corrs.abs 1 energy fat 0.786034123 0.786034123 2 energy sugars 0.354177731 0.354177731 4 energy fiber 0.283987535 0.283987535 7 energy proteins 0.234051289 0.234051289 9 sugars proteins -0.230682480 0.230682480 10 fiber proteins 0.225774683 0.225774683 8 fat proteins 0.152928421 0.152928421 20 proteins alcohol -0.117442427 0.117442427 5 fat fiber 0.095699199 0.095699199 13 sugars sodium -0.095059781 0.095059781 17 fat alcohol -0.088374917 0.088374917 15 proteins sodium 0.085165677 0.085165677 19 fiber alcohol -0.069612771 0.069612771 6 sugars fiber 0.063745522 0.063745522 26 proteins vitamin_b6 0.055244902 0.055244902 16 energy alcohol -0.046137533 0.046137533 24 sugars vitamin_b6 -0.044176940 0.044176940 18 sugars alcohol -0.036014188 0.036014188 25 fiber vitamin_b6 -0.032500956 0.032500956 21 sodium alcohol 0.031100266 0.031100266 23 fat vitamin_b6 -0.028964791 0.028964791 14 fiber sodium -0.024820173 0.024820173 3 fat sugars 0.024599048 0.024599048 11 energy sodium -0.020844735 0.020844735 27 sodium vitamin_b6 -0.019177134 0.019177134 22 energy vitamin_b6 -0.012044929 0.012044929
## 12 fat sodium 0.005943899 0.005943899 ## 28 alcohol vitamin_b6 NA NA
Las variables que presentan mayor correlación son grasas y energía (corr=0.786) plot(DFU_G[,7:8])
d) El Actimel de Danone "ayuda al funcionamiento normal del sistema inmunitario" porque contiene 0.21 mg de vitamina B6 por cada 100 g. ¿Qué porcentaje de los productos de los que en la tabla DFU_G se indica su cantidad de vitamina B6, tienen como mínimo tanta vitamina B6 por cada 100 g como el Actimel? ¿Qué 5 productos de esta tabla tienen la mayor cantidad de vitamina B6 por cada 100 g? vit=na.omit(DFU_G$vitamin_b6) length(vit) ## [1] 701 length(vit[vit>=0.00021]) ## [1] 632 length(vit[vit>=0.00021])*100/length(vit) ## [1] 90.15692
Aproximadamente el 90% de los productos tienen como mínimo tanta vitamina b6 como el actimel
dfu_maxB6=DFU_G[order(DFU_G$vitamin_b6,decreasing=TRUE),] dfu_maxB6[1:5,] ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
product_name country continent 26883 Levure de bière Vitalité Beauté France Europe 55658 Zanahorias "VegaTajo" Spain Europe 3299 Pop Tarts Hot Fudge Sundae United States North America 47915 bcaa caps France Europe 24641 Levure de bière en paillettes France Europe nutrition_grade_fr additives_n main_category 26883 a 4 Dietary supplements 55658 a 0 Plant-based foods and beverages 3299 d NA 47915 0 Bodybuilding supplements 24641 0 Groceries energy fat sugars fiber proteins sodium alcohol vitamin_b6 26883 1380.0 3.08 0.0 0.00 32.30 0.000 NA 0.2150 55658 142.8 0.30 6.8 2.60 0.80 0.070 NA 0.2000 3299 1660.0 10.40 25.0 4.17 4.17 0.396 NA 0.0208 47915 NA NA NA NA NA NA NA 0.0140 24641 1131.0 3.80 5.0 24.90 52.00 NA NA 0.0069
Los 5 productos que más B6 contienen son Levure de bière Vitalité Beauté, Zanahorias "VegaTajo&quot,; Pop Tarts Hot Fudge Sundae,bcaa caps y Levure de bière en paillettes e) Producid un gráfico que muestre, para cada continente, los diagramas de caja de las cantidades de azúcar en 100g en los productos adquiridos en el continente; y lo mismo para las cantidades de sal, de grasa y el número de aditivos. Usad el dataframe sin repeticiones dentro de continentes DFU_Continentes. ¿Se observan diferencias entre los consumos en los continentes? Comentadlas. boxplot(DFU_continente[DFU_continente$continent=="Africa",] $sugars,DFU_continente[DFU_continente$continent=="Asia",] $sugars,DFU_continente[DFU_continente$continent=="Europe",] $sugars,DFU_continente[DFU_continente$continent=="North America",] $sugars,DFU_continente[DFU_continente$continent=="South America",] $sugars,DFU_continente[DFU_continente$continent=="Oceania",] $sugars,names=c("Africa","Asia","Europa","A.Norte","A.Sur","Oceanía"),main ="Azucar")
boxplot(DFU_continente[DFU_continente$continent=="Africa",] $fat,DFU_continente[DFU_continente$continent=="Asia",] $fat,DFU_continente[DFU_continente$continent=="Europe",] $fat,DFU_continente[DFU_continente$continent=="North America",] $fat,DFU_continente[DFU_continente$continent=="South America",] $fat,DFU_continente[DFU_continente$continent=="Oceania",] $fat,names=c("Africa","Asia","Europa","A.Norte","A.Sur","OceanĂa"),main="Gr asas")
boxplot(DFU_continente[DFU_continente$continent=="Africa",] $sodium,DFU_continente[DFU_continente$continent=="Asia",] $sodium,DFU_continente[DFU_continente$continent=="Europe",] $sodium,DFU_continente[DFU_continente$continent=="North America",] $sodium,DFU_continente[DFU_continente$continent=="South America",] $sodium,DFU_continente[DFU_continente$continent=="Oceania",] $sodium,names=c("Africa","Asia","Europa","A.Norte","A.Sur","OceanĂa"),main ="Sal")
boxplot(DFU_continente[DFU_continente$continent=="Africa",] $additives_n,DFU_continente[DFU_continente$continent=="Asia",] $additives_n,DFU_continente[DFU_continente$continent=="Europe",] $additives_n,DFU_continente[DFU_continente$continent=="North America",] $additives_n,DFU_continente[DFU_continente$continent=="South America",] $additives_n,DFU_continente[DFU_continente$continent=="Oceania",] $additives_n,names=c("Africa","Asia","Europa","A.Norte","A.Sur","OceanĂa"), main="Aditivos")
f) Vamos a fijarnos ahora en las bebidas alcohólicas (aquellas que tengan valor "Beverage" en la variable main_category y contenido de alcohol mayor que 0). Usando los dataframes sin repeticiones DFU_G y DFU_Continentes, dibujad histogramas del contenido de alcohol en estas bebidas: uno global, y uno para cada continente. Procurad que los grupos sean los mismos en cada histograma (aunque algunos queden vacíos), para poder compararlos mejor. Poned nombres adecuados a los histogramas. ¿Se observan diferencias entre los continentes? ¿Qué continente presenta una distribución del contenido de alcohol en sus bebidas alcohólicas más parecido al global? ¿Se os ocurre por qué? x=DFU_G[DFU_G$main_category=="Beverages"&DFU_G$alcohol>0& ! is.na(DFU_G$alcohol),13] hist(x,main="Cantidad de alcohol en total")
x_africa=DFU_continente[DFU_continente$main_category=="Beverages"&DF U_continente$alcohol>0& ! is.na(DFU_continente$alcohol)&DFU_continente$continent=="Africa",12] hist(x_africa,main="Africa",xlim=range(0,70),ylim=range(0,500))
x_asia=DFU_continente[DFU_continente$main_category=="Beverages"&DFU _continente$alcohol>0& ! is.na(DFU_continente$alcohol)&DFU_continente$continent=="Asia",12] hist(x_asia,main="Asia",xlim=range(0,70),ylim=range(0,500))
x_europa=DFU_continente[DFU_continente$main_category=="Beverages"&D FU_continente$alcohol>0& ! is.na(DFU_continente$alcohol)&DFU_continente$continent=="Europe",12] hist(x_europa,main="Europa")
x_an=DFU_continente[DFU_continente$main_category=="Beverages"&DFU_ continente$alcohol>0& ! is.na(DFU_continente$alcohol)&DFU_continente$continent=="North America",12] hist(x_an,main="AmĂŠrica del Norte",xlim=range(0,70),ylim=range(0,500))
x_as=DFU_continente[DFU_continente$main_category=="Beverages"&DFU_c ontinente$alcohol>0& ! is.na(DFU_continente$alcohol)&DFU_continente$continent=="South America",12] hist(x_as,main="AmĂŠrica del Sur",xlim=range(0,70),ylim=range(0,500))
x_oceania=DFU_continente[DFU_continente$main_category=="Beverages"& DFU_continente$alcohol>0& ! is.na(DFU_continente$alcohol)&DFU_continente$continent=="Oceania",12] hist(x_oceania,main="OceanĂa",xlim=range(0,70),ylim=range(0,500))
Hay mucha diferencia entre los contenidos de alcohol dependiendo del continente. El que más se parece al global es el de Europa. Esto se debe a que el mayor número de observaciones procede de Europa (como se puede comprobar en la siguiente tabla) Continente=c("Total","Africa","Asia","Europa","America Norte","AmericaSur","Oceania") Alcohol=c(length(x),length(x_africa),length(x_asia),length(x_europa),length(x _an),length(x_as),length(x_oceania)) data.frame(Continente,Alcohol) ## ## ## ## ## ## ## ##
Continente Alcohol 1 Total 1444 2 Africa 3 3 Asia 5 4 Europa 1390 5 America Norte 42 6 AmericaSur 3 7 Oceania 1
g) La variable nutrition_grade_fr es un factor con niveles a,b,c,d,e. Hay otro nivel, vacío, para los productos sin categoría (correspondería al NA). Usando el data frame DFU_Continente, dibujad un diagrama de barras que muestre, para cada continente, el porcentaje de productos en cada categoría. No incluyáis los productos sin categoría asignada.
y=DFU_continente[DFU_continente$nutrition_grade_fr!="",] barplot(prop.table(table(droplevels(y$nutrition_grade_fr),y$continent))*100,b eside=TRUE,main="Categorías",legend.text = TRUE)
h) A partir del dataframe DFU_G, dibujad un gráfico que contenga los diagramas de caja de los contenidos de azúcar por 100 g de los alimentos de cada nivel de la variable nutrition_grade_fr. Repetid este gráfico para los contenidos de sal, grasa, fibra y proteínas. A partir de estos gráficos, ¿podéis interpretar cómo clasifica esta variable los alimentos? Si queréis, podéis confirmar si vuestra interpretación va en la dirección correcta consultando el informe oficial (en francés) sobre la clasificación nutricional francesa. boxplot(DFU_G[DFU_G$nutrition_grade_fr=="a",] $sugars,DFU_G[DFU_G$nutrition_grade_fr=="b",] $sugars,DFU_G[DFU_G$nutrition_grade_fr=="c",] $sugars,DFU_G[DFU_G$nutrition_grade_fr=="d",] $sugars,DFU_G[DFU_G$nutrition_grade_fr=="e",] $sugars,names=c("a","b","c","d","e"),main="Azucar")
boxplot(DFU_G[DFU_G$nutrition_grade_fr=="a",] $fat,DFU_G[DFU_G$nutrition_grade_fr=="b",] $fat,DFU_G[DFU_G$nutrition_grade_fr=="c",] $fat,DFU_G[DFU_G$nutrition_grade_fr=="d",] $fat,DFU_G[DFU_G$nutrition_grade_fr=="e",] $fat,names=c("a","b","c","d","e"),main="Grasas")
boxplot(DFU_G[DFU_G$nutrition_grade_fr=="a",] $fiber,DFU_G[DFU_G$nutrition_grade_fr=="b",] $fiber,DFU_G[DFU_G$nutrition_grade_fr=="c",] $fiber,DFU_G[DFU_G$nutrition_grade_fr=="d",] $fiber,DFU_G[DFU_G$nutrition_grade_fr=="e",] $fiber,names=c("a","b","c","d","e"),main="Fibra")
boxplot(DFU_G[DFU_G$nutrition_grade_fr=="a",] $proteins,DFU_G[DFU_G$nutrition_grade_fr=="b",] $proteins,DFU_G[DFU_G$nutrition_grade_fr=="c",] $proteins,DFU_G[DFU_G$nutrition_grade_fr=="d",] $proteins,DFU_G[DFU_G$nutrition_grade_fr=="e",] $proteins,names=c("a","b","c","d","e"),main="Proteinas")
boxplot(DFU_G[DFU_G$nutrition_grade_fr=="a",] $sodium,DFU_G[DFU_G$nutrition_grade_fr=="b",] $sodium,DFU_G[DFU_G$nutrition_grade_fr=="c",] $sodium,DFU_G[DFU_G$nutrition_grade_fr=="d",] $sodium,DFU_G[DFU_G$nutrition_grade_fr=="e",] $sodium,names=c("a","b","c","d","e"),main="Sal")