Earthshaker
Earthshaker

Reputation: 599

Calculate column wise sum for each row & add new columns for each value in dataframe

I have dataframe as below

A     B   C   D
11   11  33  44
11   11  22  33
22   22  33  44
22   33  44  11

I have such thousands of rows . Dataframe has only these four values 11, 22,33,44.

No NA or blank values

I want to take count for each of these values across every row and add them under new column.

I want output as below -

A     B   C   D  11  22  33  44
11   11  33  44   2   0   1   1
11   11  22  33   2   1   1   0
22   22  33  44   0   2   1   1
22   33  44  11   1   1   1   1

Currently i am trying as

count.22 <- sapply(dff,FUN=function(x,dff){sum(dff[,2]==22)},dff)

but its not working.

Upvotes: 1

Views: 88

Answers (2)

talat
talat

Reputation: 70336

If your data.frame is x you can do it as follows:

vals <- c(11,22,33,44)
cbind(x, setNames(lapply(vals, function(v) rowSums(x == v)), vals))
#   A  B  C  D 11 22 33 44
#1 11 11 33 44  2  0  1  1
#2 11 11 22 33  2  1  1  0
#3 22 22 33 44  0  2  1  1
#4 22 33 44 11  1  1  1  1

This way you don't loop over the rows but the unique values you want to check.

A similar version with direct assignment would be

x[,as.character(vals)] <- lapply(vals, function(v) rowSums(x == v))

Upvotes: 2

akrun
akrun

Reputation: 887851

We can use mtabulate

library(qdapTools)
df2 <- cbind(df1,  mtabulate(as.data.frame(t(df1))))
row.names(df2) <- NULL
df2
#   A  B  C  D 11 22 33 44
#1 11 11 33 44  2  0  1  1
#2 11 11 22 33  2  1  1  0
#3 22 22 33 44  0  2  1  1
#4 22 33 44 11  1  1  1  1

Or we can use apply from base R to loop over the rows

cbind(df1, t( apply(df1, 1, function(x) table(factor(x, levels = c(11, 22, 33, 44))))))

Upvotes: 2

Related Questions