89_Simple
89_Simple

Reputation: 3805

Apply a function to every row

dat <- data.frame(loc = c(1,2), year = c(1980,2012), id1 = c(5,6), id2 = c(10,12), id3 = c(14,18),id4 = c(10,12))
dat
  loc year id1 id2 id3 id4
1   1 1980   5  10  14  10
2   2 2012   6  12  18  12

For each row, I want to add id1 to id4, divide 100 by it and then multiply id1 to id4 by this factor. I have done the first part. How do I do the second part in one function?

dat$factor <- apply(dat[,3:6], 1, function(x) 100/sum(x))

How do I divide id1 by factor and id2 by factor in the same function above?

Upvotes: 1

Views: 61

Answers (2)

Maurits Evers
Maurits Evers

Reputation: 50668

You can also use direct indexing (instead of using apply):

cols <- c("id1", "id2", "id3", "id4");
dat[cols] <- dat[cols] * 100 / rowSums(dat[cols]);
#  loc year      id1      id2      id3      id4
#1   1 1980 12.82051 25.64103 35.89744 25.64103
#2   2 2012 12.50000 25.00000 37.50000 25.00000

Upvotes: 4

akrun
akrun

Reputation: 886938

Here is an option with tidyverse

library(tidyverse)
dat %>% 
   select(matches("id")) %>%
   reduce(`+`)  %>% 
   mutate(dat, new = .) %>%
   mutate_at(vars(matches("id")), funs(100*./new)) %>% 
   select(-new)
#  loc year      id1      id2      id3      id4
#1   1 1980 12.82051 25.64103 35.89744 25.64103
#2   2 2012 12.50000 25.00000 37.50000 25.00000

Or with gather/spread

dat %>%
   gather(key, val, id1:id4) %>%
   group_by(loc, year) %>%
   mutate(val = 100* val/sum(val)) %>% 
   spread(key, val)
# A tibble: 2 x 6
# Groups: loc, year [2]
#    loc  year   id1   id2   id3   id4
#* <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1  1.00  1980  12.8  25.6  35.9  25.6
#2  2.00  2012  12.5  25.0  37.5  25.0

Upvotes: 2

Related Questions