Question: I want to achieve the following behavior: 

```py
res = df.groupby(['dimension'], as_index=False)['metric'].transform(lambda x: foo(x))  

```

where foo(x) returns a series the same size as the input which is df['metric']  

however, this will throw the following error:  

ValueError: transform must return a scalar value for each group 

i know i can use a for loop style, but how can i achieve this in a groupby manner?

e.g. 

```
df:
   col1 col2 col3
0   A1  B1  1
1   A1  B1  2
2   A2  B2  3  

```

and i want to achieve: 

```
   col1 col2 col3
0   A1  B1  1 - (1+2)/2
1   A1  B1  2 - (1+2)/2
2   A2  B2  3 - 3

```

Answer: 
A first simple solution

```
# Generate a dataset
X <- data.frame(matrix(runif(1000), ncol=20))
y <- rnorm(nrow(X))
dts <- data.frame(y, X)

lms <- vector(ncol(X), mode="list")
k <- 1
for (x in names(X)) {
   # Create formula with the k-th x variabile
   frml <- as.formula(paste0("y ~", x))
   # Use the formula in a linear model
   lms[[k]] <- lm(frml, data=dts)
   k <- k+1
}
# This is the output of the linear model with the 15-th x variable
summary(lms[[15]])
# A matrix with R-squared and adjusted R-squared
r2 <- function(x) c(summary(x)$r.squared, summary(x)$adj.r.squared)
t(sapply(lms, r2))

```

A more elegant and flexible solution

```
R2 <- function(x, data) {
     frml <- as.formula(paste0("y ~", paste(unlist(x), collapse="+"))) 
     lmfit <- lm(frml, data=data)
     lmsum <- summary(lmfit)
     data.frame(R2=lmsum$r.squared, adj.R2=lmsum$adj.r.squared)
}
R2 <- Vectorize(R2, "x")

# The R-squared for all the univariate models
R2(names(X), dts)

# The R-squared for all the bivariate models 
k <- 2   
xcouples <- apply(combn(names(X), k), 2, list)
names(xcouples) <- lapply(xcouples, function(x) paste(unlist(x), collapse="_"))
t(R2(xcouples, dts))

```
To find the all possible regression outputs including multiple combinations in your data set, the codes below may help.

```
# To find all combinations of the predictors.

predictors <- names(df)[-1]
all_comb <- sapply(seq(predictors) ,function(i) {t(combn(predictors,i))})

# Calculating the regression outputs and putting into a list called result.

result <- list()

    for(x in 1:length(all_comb)){

        for(i in 1:nrow(all_comb[[x]])) {

            name <- paste(all_comb[[x]][i,], collapse = '_')
            group <- paste0("Y ~ ",paste0(all_comb[[x]][i,],collapse =" + "))
            result[[name]] <- lm(group, data =df )          

        }

     }

```

Calling `result` gives,

```
...
  ...

$x1_x3

Call:
lm(formula = group, data = df)

Coefficients:
(Intercept)           x1           x3  
     6.6647      -0.3864      -0.0954  

$x2_x3

Call:
lm(formula = group, data = df)

Coefficients:
(Intercept)           x2           x3  
     5.3037       0.1438      -0.1459  

$x1_x2_x3

Call:
lm(formula = group, data = df)

Coefficients:
(Intercept)           x1           x2           x3  
    6.16101     -0.39160      0.15794     -0.07796  

```

**Data:**

```
df <- data.frame(Y=runif(100,1,10),
    x1= runif(100,1,5),
    x2= runif(100,1,5), 
    x3= runif(100,1,5))

```