Home > Back-end >  How to do rowsums on a select set of columns containing a string and a number in R?
How to do rowsums on a select set of columns containing a string and a number in R?

Time:11-17

I have a list of column names that look like this...

               colnames(dat)
1                    subject
2                     e.type
3                      group
4                     boxnum
5                      edate
6                  file.name
7                         fr
8                     active
9                   inactive
10                    reward
11   latency.to.first.active
12 latency.to.first.inactive
13                  act0.600
14               act600.1200
15              act1200.1800
16              act1800.2400
17              act2400.3000
18              act3000.3600
19                inact0.600
20             inact600.1200
21            inact1200.1800
22            inact1800.2400
23            inact2400.3000
24            inact3000.3600
25                  rew0.600
26               rew600.1200
27              rew1200.1800
28              rew1800.2400
29              rew2400.3000
30              rew3000.3600

I want to get the row sum for the columns that list act#, inact#, and reward#

This works...

for (row in 1:nrow(dat)) {
dat[row, "active"] = rowSums(dat[row,c(13:18)])
dat[row, "inactive"] = rowSums(dat[row,c(19:24)])
dat[row, "reward"] = rowSums(dat[row,c(25:30)])
}

But I don't want to hard coded it since the number of columns for the 3 sections may change. How can I do this without hard coding the column indexes?

Also, for example, I tried searching for the "act" named columns but it was also including the "active" column.

CodePudding user response:

sub_dat <- dat[, 13:30]
result <- sapply(split.default(sub_dat, substr(names(sub_dat), 1, 3)), rowSums)
dat[, c('active', 'inactive', 'reward')]  <- result

CodePudding user response:

Easy-cheesy with witch select & matches from the tidyverse.

library(tidyverse)

data %>%
    mutate(
        sum_act = rowSums(select(., matches("act[0-9]"))),
        sum_inact = rowSums(select(., matches("inact[0-9]"))),
        sum_rew = rowSums(select(., matches("rew[0-9]")))
    )

CodePudding user response:

I made an example how it could be done:

t <- data.frame(c(1,2,3),c("a","b","c"))
colnames(t) <- c("num","char")

#with function append() you make a list of rows that fulfill your logical argument
whichRows <- append(which(t$char == "a"),which(t$char == "b"))
sum(t$num[whichRows])

or if I misunderstood you and you want to sum for every column separately then:

sum(t$num[which(t$char == "a")])
sum(t$num[which(t$char == "b")])
  •  Tags:  
  • r
  • Related