ds_user
ds_user

Reputation: 2179

Apply custom function to each subset of a data frame and result a dataframe

It may be asked many times here, but i am not able to relate it to any since my function returns data frame.

I have my custom function which builds model and outputs a data frame with slope(coeff2) in one column, intercept(coeff1) in another column, number of input records in one column ,etc. Ideally i am building my own data frame in the function and output it from the function. Now I want to subset my input data frame based on a column and apply my function on that.

Example :-

f.get_reg <- function(df) {
  linear.model <-lm(df$DM ~ df$FW,)
  N <- length(df$DM)
  slope <- coef(linear.model)[2]
  intercept <- coef(linear.model)[1]
  S <- summary(linear.model)$sigma
  df.out <- data.frame (N,slope, intercept, S)
  return (df.out)
}



sample_id     FW       DM  StdDev_DM Median_DM Count  X90 X60 crit Z.scores
     6724 116.39 16.20690    0.9560414   16.0293    60 3.35 3.2  3.2        1
     6724 116.39 16.20690    0.9560414   16.0293    60 3.35 3.2  3.2        1
     6724 110.24 16.73077    0.9560414   16.0293    60 3.35 3.2  3.2        1
     6728 110.24 16.73077    0.9560414   16.0293    60 3.35 3.2  3.2        1
     6728 112.81 16.15542    0.9560414   16.0293    60 3.35 3.2  3.2        1
     6728 112.81 16.15542    0.9560414   16.0293    60 3.35 3.2  3.2        1

Now I want to apply my function to each unique subset of sample_ids and output only one data frame with one record as an output for each subset.

Upvotes: 3

Views: 2861

Answers (1)

shrgm
shrgm

Reputation: 1334

dplyr

You could use do in dplyr:

library(dplyr)
df %>%
    group_by(sample_id) %>%
    do(f.get_reg(.))

Which gives:

  sample_id     N       slope intercept            S
      (int) (int)       (dbl)     (dbl)        (dbl)
1      6724     3 -0.08518211  26.12125 7.716050e-15
2      6728     3 -0.22387160  41.41037 5.551115e-17

data.table

Use .SD in data.table:

library(data.table)

df <- data.table(df)
df[,f.get_reg(.SD),sample_id]

Which gives the same result:

   sample_id N       slope intercept            S
1:      6724 3 -0.08518211  26.12125 7.716050e-15
2:      6728 3 -0.22387160  41.41037 5.551115e-17

base R

Using by:

resultList <- by(df,df$sample_id,f.get_reg)
sample_id <- names(resultList)
result <- do.call(rbind,resultList)
result$sample_id <- sample_id
rownames(result) <- NULL

Which gives:

  N       slope intercept            S sample_id
1 3 -0.08518211  26.12125 7.716050e-15      6724
2 3 -0.22387160  41.41037 5.551115e-17      6728

Upvotes: 7

Related Questions