Rocky
Rocky

Reputation: 93

Apply function to rows return vector instead of list

I have a data frame (below is simplified version)

b<-data.frame('v1'=1:2,'v2'=3:4,'v3'=5:6)

If I use apply on rows:

test<-apply(b,1,function(x) {if (x[length(x)]>0) return (x/x[length(x)]) else return (0)})

I got:

[,1]      [,2]
v1  0.2 0.3333333
v2  0.6 0.6666667
v3  1.0 1.0000000

So far so good since I do need the column name v1,v2,v3 becomes row names in test. But if the data frame is all zeros,

b1<-data.frame('v1'=c(0,0),'v2'=c(0,0),'v3'=c(0,0))
test<-apply(b1,1,function(x) {if (x[length(x)]>0) return (x/x[length(x)]) else return (0)})

test will return a vector as 0 0 My question is how to let test return something like

[,1]      [,2]
v1  0      0
v2  0      0
v3  0      0

Basically if the last one in a row is zero I want to make everything in the row as 0 and more importantly I want the return is a list so that I got the v1,v2,v3 row names (I can change to data frame if the return is list), now the return is vector 0,0 I lost all the information of v1, v2, v3. Why all zeros make such a difference?

Upvotes: 3

Views: 1972

Answers (1)

Sraffa
Sraffa

Reputation: 1668

Why not just create a function that divides the dataframe by the last column and then substitutes NAs with zeroes?

prop_last_col <- function(df) {
        prop <- df / df[, ncol(df)]
        prop[is.na(prop)] <- 0
        return(prop)
    }

prop_last(b)
         v1        v2 v3
1 0.2000000 0.6000000  1
2 0.3333333 0.6666667  1


 prop_last(b1)
  v1 v2 v3
1  0  0  0
2  0  0  0

If you want it to be in the same format as your example you could just transpose the results.

Upvotes: 1

Related Questions