JimO
JimO

Reputation: 11

Count by row with variable criteria

I have a data.frame in which I want to perform a count by row versus a specified criterion. The part I cannot figure out is that I want a different count criterion for each row.

Say I have 10 rows, I want 10 different criteria for the 10 rows.

I tried: count.above <- rowSums(Data > rate), where rate is a vector with the 10 criterion, but R used only the first as the criterion for the whole frame.

I imagine I could split my frame into 10 vectors and perform this task, but I thought there would be some simple way to do this without resorting to that.

Upvotes: 1

Views: 123

Answers (2)

stephematician
stephematician

Reputation: 884

Given the dummy data (from @zx8754s solution)

# dummy data
df1 <- data.frame(matrix(1:15, nrow = 3))

myRate <- c(7, 5, 1)

Solution using apply

Courtesy of @JDL

rowSums(apply(df1, 2, function(v) v > myRate))

Alternative solution using the Reduce pattern

Reduce(function(l, v) cbind(l[,1] + (l[,2] > myRate), l[,-2:-1]),
       1:ncol(df1),
       cbind(0, df1))

Upvotes: 0

JDL
JDL

Reputation: 1654

Edit: this depends whether you want to operate over rows or columns. See below:

This is a job for mapply and Reduce. Suppose you have a data frame along the lines of

df1 <- data.frame(a=1:10,b=2:11,c=3:12)

Let's say we want to count the rows where a>6, b>3 and c>5. This is done with mapply:

mapply(">",df1,c(6,3,5),SIMPLIFY=FALSE)

$a
[1] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE

$b
[1] FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE

$c
[1] FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE

Now we use Reduce to find those which are all TRUE:

Reduce("&",mapply(">",df1,c(6,3,5),SIMPLIFY=FALSE))
[1] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE

Lastly, we use sum to add them all up:

sum(Reduce("&",mapply(">",df1,c(6,3,5),SIMPLIFY=FALSE)))
[1] 4

If you want a result for each row rather than a global aggregate, then apply is the function to use:

apply(df1,1,function(v) sum(v>c(6,3,5)))
[1] 0 0 1 2 2 2 3 3 3 3

Upvotes: 1

Related Questions