Tools/rstudio

From Open Food Facts wiki
Jump to navigation Jump to search

Rstudio is a tool do do statistical analysis on data.

Recipe

The tool can be used to find the recipe of products.

Steps

We use the order as found on packaging, i.e. fat, sat. fat, carbs, sugar, fiber, proteins, salt).

Create the product data, e.g:

product <- c(58.0, 6.4, 6.4, 4.2, 8.5, 0.01)

Create the individual ingredients, eg.:

walnuts <- c(67.3, 6.45, 6.88, 3, 6.7, 13.3, 0.1)

Create the ingredients, e.g.:

ingredients <- c(walnuts, hazelnuts, cashews, almonds)

Create the array for 4 ingredients, e.g.:

Z <-array(ingredients, dim=c(7,4))

Fit:

lsFit <- lm(y~Z)

Fit with no intercept:

lsFitZero <- lm(y~Z +0)

Fit with no negative coefficients:

nnFit <- nnls(Z,y)

GLMN-fit

glmnetFit <- glmnet(Z,y, lambda = 0, lower.limit = 0, intercept = FALSE)

Dataframe:

plotData <- data.frame(variance,residuals)

Graph

ggplot(plotData, aes(variance,residuals)) + geom_point() + labs(title="Comparing ingredients") + annotate(geom = "text", x = 0.4, y = 0.1, label = "Wheat 110 + butter") + annotate(geom = "text", x = 1.4, y = 0.8, label = "Wheat 110 + butteroil") + annotate(geom = "text", x = 1.4, y = 0.2, label = "Wheat 150 + butter") + annotate(geom = "text", x = 0.4, y = 0.9, label = "Wheat 80 + butter")

Nutrients blame chart

What ingredients are to blame for a specific nutrient? Can work with a stacked barchart. Each Nutrient on the horizontal axis. Each bar shows which ingredient has contributed to that nutrient. Each ingredient should have its own colour.

For each ingredient we have a coefficient. This coefficient should be multiplied with nutritional values. So we get an array for each nutrient. This should be fed into the dataFrame.

Ingredient order constraint

In order to enforce the ingredient order in the R models, things need to be done differently. The model must be closer to a multivariate version. Need to experiment how this can be done.

An approach is to assume that the data for each ingredient is a measurement. Thus we will have 7 measurements. This will be put in an array with 7 rows and 1 column. This must be done for each ingredient. And the names of the columns can be given as well, which helps handling later.

pm <- matrix(product, nrow=7, ncol=1)

This needs to be repeated for each ingredient. Then we can combine everything into a matrix:

cake <- cbind(pm, fm, eggsm, sugarm, butterm, saltm)

Or with, so each column gets a header:

cakeFrame <- data.frame(product=pm, flour=fm, eggs=eggsm, sugar=sugarm, butter=butterm, salt=saltm)

The fit is then (forcing origin):

fitZero <- lm(product ~ flour+eggs+sugar+butter+salt+0,cakeFrame)

This works as well, but has an offset:

fit <- penalized(product, ~ flour+eggs+sugar+butter+salt+0, ~1, lambda1=0,lambda2=0, positive=FALSE,data=cakeFrame)

And to force an offset of zero:

fit <- penalized(product, product ~ flour + eggs + sugar + butter, salt + 0, lambda1= 0, lambda2= 0, positive= FALSE, data= cakeFrame)

To force non-negative:

fit <- penalized(product, product ~ flour + eggs + sugar + butter, salt + 0, lambda1= 0, lambda2= 0, positive= c(T, T, T, T), data= cakeFrame)

This package works as well:

fitC <- ConsReg(product ~ flour + eggs + sugar + butter + salt + 0, family = 'gaussian', optimizer = 'mcmc', data= cakeFrame)

Is this the same:

fitC <- ConsReg(product ~ flour + eggs + sugar + butter + salt + 0, family = 'gaussian', optimizer = 'mcmc', constraints = 'flour > 0, eggs > 0, sugar > 0, butter >0, salt > 0', data= cakeFrame)

Adding the order constraint:

fitC <- ConsReg(product ~ flour + eggs + sugar + butter + salt + 0, family = 'gaussian', optimizer = 'mcmc', constraints = 'flour > eggs, eggs > sugar, sugar > butter, butter > salt, salt > 0', data= cakeFrame)

Solutions above do not work. Better rewrite the formula's (adding ingredients):

ingP13 <- ingP12 + flour

Create a matrix with added ingrdients:

Z <- array(c(milk, ingP2, ingP3, ingP4, ingP5, ingP6, ingP7, ingP8, ingP9, ingP10, ingP11, ingP12, ingP13), dim=c(7,13))

And do the nnls fit:

fit14 <- nnls(Z,product)

Residuals plot

Create a residuals frame:

resFrame <- data.frame( nutrients=nutrients,fit2=nFit2"residuals", fit3=nFit3"residuals", fit4=nFit4"residuals", fit5=nFit5"residuals",fit6=nFit6"residuals",fit7=nFit7"residuals", fit8=nFit8"residuals", fit9=nFit9"residuals", fi104=nFit10"residuals", fit11=nFit11"residuals", fit12=nFit12"residuals", fit13=nFit13"residuals",fit14=nFit14"residuals")

Melt the frame:

resFrameM <- melt(resFrame, id.vars="nutrients",value.name="residuals", variable.name="fit")

Plot:

ggplot(resFrameM, aes(x=nutrients,y=residuals, group=fit, colour=fit))+geom_line()

Recipe plot

f1mushroom <- nFit2"x"[2]
f1milk <- nFit2"x"[1] + f1mushroom
ingredients <- c("Milk", "Mushroom")
recipeFrame <- data.frame( ingredients=ingredients,fit1=rbind( f1milk, f1mushroom))
recipeMelt <- melt(recipeFrame, id.vars="ingredients",value.name="fraction", variable.name="fit")

Order the plot similar to the ingredient list:

recipeMelt$ingredients <- factor(recipeMelt$ingredients, levels=ingredients)
ggplot(recipeMelt, aes(x=fit,y=fraction, group=ingredients, colour=ingredients, fill=ingredients)) + geom_col(position="stack")