Í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(urlhttps://miriadax.net/documents/28098821/74010125/FoodFactsMooc.csv/c1b38463 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. 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? 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 útil dentro de un rato), donde cada producto aparezca una sola vez.
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.
DF_G=read.table("https://miriadax.net/documents/28098821/74 010125/FoodFactsMooc.csv/c1b38463-6006-4a3b-b94aa72d31d54831", sep=",",header=TRUE) #Data.frames por continentes:
DF_Europa=DF_G[DF_G$continent=='Europe',] DF_Asia=DF_G[DF_G$continent=='Asia',] DF_Africa=DF_G[DF_G$continent=='Africa',] DF_Oceania=DF_G[DF_G$continent=='Oceania',] DF_AmericaS=DF_G[DF_G$continent=='South America',] DF_AmericaN=DF_G[DF_G$continent=='North America',] #Data.frame sin países ni contenentes: DFU_G=unique(DF_G[,-c(2, 3)]) #Data.frame sin países y por contenentes: DFU_Europa=unique(DF_Europa[,-c(2)]) DFU_Asia=unique(DF_Asia[,-c(2)]) DFU_Africa=unique(DF_Africa[,-c(2)]) DFU_Oceania=unique(DF_Oceania[,-c(2)]) DFU_AmericaS=unique(DF_AmericaS[,-c(2)]) DFU_AmericaN=unique(DF_AmericaN[,-c(2)]) #Número de repeticiones de la tabla de datos original: dim(DF_G)[1]-dim(DFU_G)[1] #38944-37415=1529 #Data.frame de todos los contenentes: DFU_Continentes=rbind(DFU_Europa, DFU_Asia, DFU_Africa, DFU_AmericaN, DFU_AmericaS, DFU_Oceania)
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? DFU_G_nutrition_NA=DFU_G[DFU_G$nutrition_grade_fr=='NA',2] nutrition_NA=length(DFU_G_nutrition_NA) DFU_G_additives_NA=DFU_G[DFU_G$additives_n=='NA',3] additives_NA=length(DFU_G_additives_NA) DFU_G_category_NA=DFU_G[DFU_G$main_category=='NA',4] category_NA=length(DFU_G_category_NA) DFU_G_energy_NA=DFU_G[DFU_G$energy=='NA',5] energy_NA=length(DFU_G_energy_NA)
DFU_G_fat_NA=DFU_G[DFU_G$fat=='NA',6] fat_NA=length(DFU_G_fat_NA) DFU_G_fats_NA=DFU_G[DFU_G$fats=='NA',7] fats_NA=length(DFU_G_fats_NA) DFU_G_fiber_NA=DFU_G[DFU_G$fiber=='NA',8] fiber_NA=length(DFU_G_fiber_NA) DFU_G_proteins_NA=DFU_G[DFU_G$proteins=='NA',9] proteins_NA=length(DFU_G_proteins_NA) DFU_G_sodium_NA=DFU_G[DFU_G$sodium=='NA',10] sodium_NA=length(DFU_G_sodium_NA) DFU_G_alcohol_NA=DFU_G[DFU_G$alcohol=='NA',11] alcohol_NA=length(DFU_G_alcohol_NA) DFU_G_vitaminB6_NA=DFU_G[DFU_G$vitamin_b6=='NA',12] vitaminB6_NA=length(DFU_G_vitaminB6_NA) Nulos =c(nutrition_NA, additives_NA, category_NA, energy_NA, fat_NA, fats_NA, fiber_NA, proteins_NA, sodium_NA, alcohol_NA, vitaminB6_NA) Porc=round(Nulos/383.35, 2) DFU_G_NA=cbind(Nulos, Porc) dimnames(DFU_G_NA)=list(c("nutrition_fr", "addditives_n", "main_category","energy","fat","fats","fiber", "proteins","sodium", "alcohol", "vitamin_b6"), c("Nulos", "%"))
Las variables que parecen mostrar un mayor porcentaje de NAs son el alcohol y la proteína b6.En los alimentos no hay alcohol, por lo que en la mayoría de los casos, se verá representada la variable o con un 0 o NA. Si se atiende, por otro lado, al contenido de vitamina b6 en los alimentos, es necesario indicar que esta vitamina no se encuentra presente en todos ellos, sino que cada uno está contiene sus propias vitaminas específicas. Por este motivo, se recogen tantos alimentos en los que no se ha detectado la vitamina.
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: 1. Si lo habéis hecho bien, aparecerá una sola pareja de variables con correlación NA. ¿A qué se debe este valor? x=abs(cor(DFU_G[,5:12 ], use="na.or.complete" )) y=abs(cor(DFU_G[,5:12 ], use="complete.obs" )) z=abs(cor(DFU_G[,5:12], use="pairwise.complete.obs" ))
De entre todas las formas de aplicar use se puede elegir entre las opciones na.or.complete, complete.obs, pairwise.complete.obs. Tras probar todas se determina que la mejor es pairwise.complete.obs. El hecho de que no se obtenga correlación en este caso entre el alcohol y la vitamina b6 se debe a que las bebidas alcohólicas no contienen vitaminas a diferencia de algunos alimentos, los cuales tampoco presentan contenido alcohólico. heatmap(z, margins=c(9,9), symm=TRUE, Rowv=NA, Colv=NA, revC=TRUE, main="Diagrama de calor de las correlaciones entre variables")
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. lm(DFU_G$energy~DFU_G$fat)$coefficients summary(lm(DFU_G$energy~DFU_G$fat))$r.squared #y=611.98812+36.42419X
R = 0.6187224
plot(DFU_G$fat,DFU_G$energy, main="Diagrama de dispersión del par de variables numéricas diferentes \n con mayor correlación en valor absoluto", xlab="Grasas",ylab="Energía") abline(611.98812,36.42419, col="red",lwd=3)
Existe una mayor correlación entre energía y grasas. La mayor cantidad de energía que se encuentra en los alimentos está acumulada en forma de grasas, sobrepasando incluso en muchos casos a los azúcares por ser fuentes energéticas de reserva. 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? DFU_G_vit=DFU_G[order(-DFU_G$vitamin_b6),c(1,12)] #Obtenemos cuantos productos tienen, al menos, 0.00021 gr de vitamina_b6 /100gr de producto. num_prod=length(which(DFU_G_vit$vitamin_b6>=0.00021)) DFU_G_vit[num_prod,] DFU_G_vit[num_prod+1,] #Calculamos el porcentaje sobre el total de filas de DFU_G porc_prod=num_prod/dim(DFU_G)[1]*100 #Para obtener los cinco primeros DFU_G_vit[1:5,] 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 ( sugars ~ continent , data = DFU_Continentes , main ="Contenido de azúcar en 100g del producto \n por continentes parcial", notch =TRUE ,ylim=c(0,110), ylab ="Azúcar (en g)", col=1:6)
boxplot ( fat ~ continent , data = DFU_Continentes , main ="Contenido de grasa en 100g del producto \n por continentes parcial", notch =TRUE ,ylim=c(0,110), ylab ="Grasa (en g)", col=1:6)
boxplot ( sodium ~ continent , data = DFU_Continentes , main ="Contenido de sal en 100g del producto \n por continentes parcial", notch =TRUE , ylim=c(0,1.5), ylab ="Sal (en g)", col=1:6)
boxplot ( additives_n ~ continent , data = DFU_Continentes , main ="NĂşmero de aditivos del producto \n por continentes parcial", notch =TRUE , ylim=c(0,15), ylab ="NĂşmero de aditivos", col=1:6)
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é? alc_G=subset(DFU_G, main_category=="Beverages" & alcohol>0)$alcohol alc_Africa=subset(DFU_Africa, main_category=="Beverages" & alcohol>0)$alcohol alc_Asia=subset(DFU_Asia, main_category=="Beverages" & alcohol>0)$alcohol alc_AmericaN=subset(DFU_AmericaN, main_category=="Beverages" & alcohol>0)$alcohol alc_AmericaS=subset(DFU_AmericaS, main_category=="Beverages" & alcohol>0)$alcohol alc_Europa=subset(DFU_Europa, main_category=="Beverages" & alcohol>0)$alcohol alc_Oceania=subset(DFU_Oceania, main_category=="Beverages" & alcohol>0)$alcohol #Utilización de la regla de Scott k=nclass.scott(alc_G) a=round(diff(range(alc_G))/k,1) L =min(alc_G)-0.1/2 + a * (0:k) hist_rel=function(x,L,main=""){ h=hist(x, breaks=L, right=FALSE, plot=FALSE) t=round(1.1*max(max(density(x)[[2]]),h$density),3) plot(h, freq=FALSE, col="yellow", main=cbind("Histograma de frec. relativas y curva de densidad estimada de",main), xaxt="n", ylim=c(0,t), xlab="Intervalos", ylab="Densidades") axis(1, at=L) text(h$mids, h$density/2, labels=round(h$counts/length(x),2), col="black") lines(density(x), col="blue", lwd=2) }
hist_rel(alc_G,L, "el mundo")
hist_rel(alc_Africa,L, "Ă frica")
hist_rel(alc_Asia,L,"Asia")
hist_rel(alc_AmericaN,L,"AmericaN")
hist_rel(alc_AmericaS,L,"AmericaS")
hist_rel(alc_Europa,L,"Europa")
hist_rel(alc_Oceania,L,"Oceania") # No es posible dibujar un gráfico para Oceanía Las comparaciones obtenidas entre los diversos continentes no hacen otra cosa que evidenciar las marcadas diferencias entre ellos, siendo Europa el continente con un resultado resultado más parecido al global. length(DFU_Continentes[,1])-length(DFU_Europa[,1])
#Solo 2336 productos no se producen en Europa. El hecho de que los productos sean de origen francés concuerda con los resultados obtenidos para Europa, ya que es el continente en el que se integra Francia. Por este motivo, la mayor parte de la importación que reciba procederá de países vecinos europeos.
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. clas.na=DFU_Continentes$nutrition_grade_fr=="" clas=DFU_Continentes[clas.na==FALSE, ] clas=clas[,c(3,2)] clas$nutrition_grade_fr=factor(clas$nutrition_grade_fr,levels(cl as$nutrition_grade_fr)[-1]) barplot(prop.table(table(clas), margin=2)*100, col=1:5, ylim=c(0,100),legend.text=TRUE, main="Porcentaje de productos en cada \n categoría por continente")
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 ( sugars ~ nutrition_grade_fr , data = DFU_G , main ="Contenido de azúcar en 100g del producto \n por grado nutricional parcial", notch =TRUE , ylimits=c(0,95), ylab ="Azúcar (en g)", col=1:6)
boxplot ( fat ~ nutrition_grade_fr , data = DFU_G , main ="Contenido de grasa en 100g del producto \n por grado nutricional parcial", notch =TRUE , ylimits=c(0,60), ylab ="Grasa (en g)", col=1:6)
boxplot ( proteins ~ nutrition_grade_fr , data = DFU_G , main ="Contenido de proteína en 100g del producto \n por grado nutricional parcial", notch =TRUE , ylimits=c(0,30), ylab ="Proteínas (en g)", col=1:6)
boxplot ( fiber ~ nutrition_grade_fr , data = DFU_G , main ="Contenido de fibra en 100g del producto \n por grado nutricional parcial", notch =TRUE ,ylimits=c(0,10), ylab ="Fibra (en g)", col=1:6)
Se observa que a mayor cantidad de azĂşcar y de grasas, mĂĄs avanzada es la letra del abecedario. Se intuye con respecto a la fibra que va decayendo al avanzar las mientras que con las proteĂnas no se puede obtener un resultado concreto.