Reputation: 93
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
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