简体   繁体   中英

how to add value of different column with respect of a column

suppose I have

SAMPN      PERNO     loop     car   bus   walk    mode
  1          1         1        3.4   2.5  1.5     1
  1          1         1        3      2   1       2
  1          1         1        4      2   5       3
  1          1         2        14     1   3       1
  1          1         2        5      8   2       1
  2          1         1        1      5   5       3
  2          1         1        9      4   3       3

mode column is crossponding to car bus and walk.

mode==1    walk
mode==2    car
mode==3    bus

SAMPN is index of family, PERNO members in family and loop tour of each person. I want to add the value of mode of each person in each family in each loop.

for example in first family SAMPN==1 first person PERNO==1 we have 3 rows for first trip loop==1 . in this tour mode of first row is walk ( mode==1 ),mode of second row is car ( mode==2 ),mode of third row is bus ( mode==3 )

so I will add walk of first row by car of second and bus of third 3.4+2+5=10.4. same for others

Output:

SAMPN      PERNO     loop     car   bus   walk    mode   utility
  1          1         1        3.4   2.5  1.5     1   10.4
  1          1         1        3      2   1       2   10.4
  1          1         1        4      2   5       3   10.4
  1          1         2        14     1   3       1   19
  1          1         2        5      8   2       1   19
  2          1         1        1      5   5       3   8
  2          1         1        9      4   3       3   8
df %>%
  mutate(utility = case_when(mode == 1 ~ car,   # using the order in the example,
                             mode == 2 ~ bus,   #   not the order in the table
                             mode == 3 ~ walk,
                             TRUE ~ 0)) %>%
  count(SAMPN, PERNO, loop, wt = utility, name = "utility")

## A tibble: 3 x 4
#  SAMPN PERNO  loop utility
#  <int> <int> <int> <dbl>
#1     1     1     1  10.4
#2     1     1     2  19  
#3     2     1     1   8 

Or, to get the exact output:

df %>%
  mutate(utility= case_when(mode == 1 ~ car,
                            mode == 2 ~ bus,
                            mode == 3 ~ walk,
                            TRUE ~ 0)) %>%
  group_by(SAMPN, PERNO, loop) %>%
  mutate(utility = sum(utility))

## A tibble: 7 x 8
## Groups:   SAMPN, PERNO, loop [3]
#  SAMPN PERNO  loop   car   bus  walk  mode utility
#  <int> <int> <int> <dbl> <dbl> <dbl> <int> <dbl>
#1     1     1     1   3.4   2.5   1.5     1  10.4
#2     1     1     1   3     2     1       2  10.4
#3     1     1     1   4     2     5       3  10.4
#4     1     1     2  14     1     3       1  19  
#5     1     1     2   5     8     2       1  19  
#6     2     1     1   1     5     5       3   8  
#7     2     1     1   9     4     3       3   8 

Here is an option using base R . Create a column index matching the 'mode' with a named column name ('nm1'0, then cbind with row index, extract the corresponding elements from the dataset, use ave to get th e sum grouped by 'SAMPN', and 'loop' column to assign it to 'utility'

nm1 <- setNames(names(df1)[4:6], 1:3)[as.character(df1$mode)]
i1 <- cbind(seq_len(nrow(df1)), match(nm1, names(df1)))    
df1$utility <- ave(df1[i1], df1$SAMPN, df1$PERNO, df1$loop, FUN = sum)
df1$utility
#[1] 10.4 10.4 10.4 19.0 19.0  8.0  8.0

data

df1 <- structure(list(SAMPN = c(1L, 1L, 1L, 1L, 1L, 2L, 2L), PERNO = c(1L, 
1L, 1L, 1L, 1L, 1L, 1L), loop = c(1L, 1L, 1L, 2L, 2L, 1L, 1L), 
    car = c(3.4, 3, 4, 14, 5, 1, 9), bus = c(2.5, 2, 2, 1, 8, 
    5, 4), walk = c(1.5, 1, 5, 3, 2, 5, 3), mode = c(1L, 2L, 
    3L, 1L, 1L, 3L, 3L)), class = "data.frame", row.names = c(NA, 
-7L))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM