user5873893
user5873893

Reputation:

Multiplying column names/factors by each row

Hi I'm new to R an have my first problem,

I have basically a data structure that looks pretty similar to:

ID <- c(1,2,3)
C <- c(0.4,0.4,0.2)
B <- c(0.4,0.3,0.2)
A <- c(0.2,0.3,0.6)
df <- data.frame(ID,A,B,C)

head(df)

  ID   A   B   C
1  1 0.2 0.4 0.4
2  2 0.3 0.3 0.4
3  3 0.6 0.2 0.2

where A,B,C correspond to grades A=1,B=2,C=3

I would like to compute the weighted average column for each row like:

ID 1   A*0.2 + B*0.4 + C*0.4
...

I tried:

as.numeric(as.character(names(df[,2:ncol(df)]))) * df[2:nrow(df),]

But that seems not right.

Upvotes: 1

Views: 78

Answers (4)

Frank
Frank

Reputation: 66819

A standard way is: Put your thingamabob into an object

grades = c(A=1,B=2,C=3)

Then map-reduce

df$wt_grade = Reduce(`+`, Map(`*`, df[names(grades)], grades))
# or
df$wt_grade = Reduce(`+`, lapply(names(grades), function(x) df[[x]] * grades[x]))

The latter approach, borrowed from @eddi, is pretty fast.

Manually writing out the expression in terms of A, B and C (as in some other answers) will not extend well to additional grades or modifying the values associated with each grade.

Upvotes: 3

rafa.pereira
rafa.pereira

Reputation: 13807

A simple and fast solution using the data.table approach

library(data.table)

setDT(df)[, w_avg :=  (A + B*2 + C*3)/(A+B+C) ] 

Upvotes: 0

Edward R. Mazurek
Edward R. Mazurek

Reputation: 2177

Using dplyr/tidyr:

library(dplyr)
library(tidyr)
df %>%
  gather(grade, value, -ID) %>%
  group_by(ID) %>%
  summarize(WtAvg = sum(as.numeric(grade) * value))

Upvotes: 0

akuiper
akuiper

Reputation: 214927

Something like this?

df$WtAvg = with(df, A + 2*B + 3*C)

df
  ID   A   B   C WtAvg
1  1 0.2 0.4 0.4   2.2
2  2 0.3 0.3 0.4   2.1
3  3 0.6 0.2 0.2   1.6

Upvotes: 2

Related Questions