tospig
tospig

Reputation: 8343

R Apply calculation on each row and column of data frame

In a data frame I want to subtract the mean of each column, from every element of that column.

Example data frame:

x <- c(1,2,3,4,5,6,7,8,9,10)
y <- c(2,3,2,3,2,3,2,3,2,3)
z <- c(100,200,300,400,500,600,700,800,900,1000)
df <- data.frame(x, y, z)

# get the mean of each column
mu <- colMeans(df)

I think I need to be using sapply, similar to:

df_norm <- df
df_norm[,1] <- sapply(df[,1], function(x) (x-mu[1]))
df_norm[,2] <- sapply(df[,2], function(x) (x-mu[2]))
df_norm[,3] <- sapply(df[,3], function(x) (x-mu[3]))

but I can't figure out how to write the FUN argument to do this in one line of code.

Upvotes: 1

Views: 14475

Answers (3)

Athos
Athos

Reputation: 660

sapply(df, function(x){x-mean(x)})

Upvotes: 2

flodel
flodel

Reputation: 89107

To keep a data.frame structure, you can do:

as.data.frame(Map(`-`, df, mu))

or

sweep(df, 2, mu)

There is also the scale function that is pretty convenient but it does convert your data to a matrix:

scale(df, center = TRUE, scale = FALSE)

If you do not mind converting to a matrix, then you can also do:

t(t(df) - mu)

Upvotes: 2

jlhoward
jlhoward

Reputation: 59425

Here's one way:

do.call(cbind,lapply(df,function(col)col-mean(col)))
#          x    y    z
#  [1,] -4.5 -0.5 -450
#  [2,] -3.5  0.5 -350
#  [3,] -2.5 -0.5 -250
#  [4,] -1.5  0.5 -150
#  [5,] -0.5 -0.5  -50
#  [6,]  0.5  0.5   50
#  [7,]  1.5 -0.5  150
#  [8,]  2.5  0.5  250
#  [9,]  3.5 -0.5  350
# [10,]  4.5  0.5  450

Upvotes: 2

Related Questions