Reputation: 139
Sample code and data:
attach(CO2)
head(CO2)
Plant Type Treatment conc uptake
1 Qn1 Quebec nonchilled 95 16.0
2 Qn1 Quebec nonchilled 175 30.4
3 Qn1 Quebec nonchilled 250 34.8
4 Qn1 Quebec nonchilled 350 37.2
5 Qn1 Quebec nonchilled 500 35.3
6 Qn1 Quebec nonchilled 675 39.2
fcv <- by(CO2, CO2[, c("Plant", "Type", "Treatment")], function(m) fitted(lm(m[,5] ~ m[,4])))
fcv
Plant: Qn1
Type: Quebec
Treatment: nonchilled
1 2 3 4 5 6 7
26.94781 28.42563 29.81110 31.65838 34.42931 37.66205 43.66573
------------------------------------------------------------
Plant: Qn2
Type: Quebec
Treatment: nonchilled
1 2 3 4 5 6 7
26.47555 28.51828 30.43334 32.98674 36.81686 41.28533 49.58391
------------------------------------------------------------
Plant: Qn3
Type: Quebec
Treatment: nonchilled
1 2 3 4 5 6 7
29.71856 31.57638 33.31808 35.64035 39.12376 43.18774 50.73512
------------------------------------------------------------
Plant: Qc1
Type: Quebec
Treatment: nonchilled
NULL
------------------------------------------------------------
and so on.
Problem:
I would like to add an extra column to the base dataset, or create a new dataset with an added column which shows the predicted value of the uptake based on the column. Something like:
Plant Type Treatment conc uptake predicted_uptake
1 Qn1 Quebec nonchilled 95 16.0 26.96781
Thanks, d_j
Upvotes: 0
Views: 39
Reputation: 269985
1) Try ave
:
Fit <- function(ix) if (length(ix)) fitted(lm(uptake ~ conc, CO2, subset = ix))
transform(CO2, fitted = ave(1:nrow(CO2), Plant, Type, Treatment, FUN = Fit))
2) or with by
:
addFit <- function(DF) transform(DF, fit = fitted(lm(uptake ~ conc, DF)))
by(CO2, CO2[1:3], addFit)
2a) or perhaps replace the last line with:
do.call(rbind, by(CO2, CO2[1:3], addFit))
3) or with data.table
library(data.table)
DT <- data.table(CO2)
DT[, fit := fitted(lm(uptake ~ conc, .SD)), by = CO2[1:3]]
Upvotes: 1
Reputation: 887691
You could use dplyr
library(dplyr)
res <- CO2 %>%
group_by(Plant, Type, Treatment) %>%
do(data.frame(.,prediced_uptake=fitted(lm(uptake~conc, data=.))))
head(res)
# Plant Type Treatment conc uptake prediced_uptake
#1 Qn1 Quebec nonchilled 95 16.0 26.94781
#2 Qn1 Quebec nonchilled 175 30.4 28.42563
#3 Qn1 Quebec nonchilled 250 34.8 29.81110
#4 Qn1 Quebec nonchilled 350 37.2 31.65838
#5 Qn1 Quebec nonchilled 500 35.3 34.42931
#6 Qn1 Quebec nonchilled 675 39.2 37.66205
Or using by
f1 <- function(m) cbind(m, predicted_uptake=fitted(lm(m[,5]~m[,4])))
res2 <- do.call(`rbind`, by(CO2, CO2[,c('Plant', 'Type','Treatment')],f1))
head(res2)
# Plant Type Treatment conc uptake predicted_uptake
#1 Qn1 Quebec nonchilled 95 16.0 26.94781
#2 Qn1 Quebec nonchilled 175 30.4 28.42563
#3 Qn1 Quebec nonchilled 250 34.8 29.81110
#4 Qn1 Quebec nonchilled 350 37.2 31.65838
#5 Qn1 Quebec nonchilled 500 35.3 34.42931
#6 Qn1 Quebec nonchilled 675 39.2 37.66205
Or using data.table
library(data.table)
res3 <- setDT(CO2)[, predicted_uptake:=
fitted(lm(uptake~conc, data=.SD)), by=list(Plant,Type, Treatment)]
head(res3)
# Plant Type Treatment conc uptake predicted_uptake
#1: Qn1 Quebec nonchilled 95 16.0 26.94781
#2: Qn1 Quebec nonchilled 175 30.4 28.42563
#3: Qn1 Quebec nonchilled 250 34.8 29.81110
#4: Qn1 Quebec nonchilled 350 37.2 31.65838
#5: Qn1 Quebec nonchilled 500 35.3 34.42931
#6: Qn1 Quebec nonchilled 675 39.2 37.66205
Upvotes: 1