I am trying to add a column in my DataFrame that represents the mean of many other columns (items that represent a single construct).
The dataframe has many other columns but particularly columns eng1, eng2, eng3...engN where N is a large number and I want to take the mean of all the eng* columns and add that mean as a new column to my dataset.
I was able to do this with the following code:
narrow_ds # ... initialization of dataframe
library(dplyr)
narrow_ds <- bind_cols(narrow_ds, (narrow_ds %>% 
select(starts_with("eng")) %>% mutate(eng=rowMeans(., na.rm=TRUE))) %>% 
select(eng))
It seems that having the na.rm=TRUE requirement forced me to jump through some hoops.
My question is whether there are more straightforward ways to do this?
You are very much in right direction. You can avoid bind_cols with a tweak in your code. Moreover, the NA are supported even in rowMeans. I have modified the sample data used by @Tung to include few NAs as well. The solutions can be as:
Option#1: Using dplyr in similar approach as OP. 
library(dplyr)
DF %>% mutate(eng = rowMeans(select(.,starts_with("eng")), na.rm = TRUE))
# # A tibble: 4 x 5
#      id  eng1  eng2  eng3   eng
#   <int> <dbl> <dbl> <dbl> <dbl>
# 1     1  50.0    NA  20.0  35.0
# 2     2  NA     100  10.0  55.0
# 3     3  20.0   150  80.0  83.3
# 4     4  30.0   200  40.0  90.0
Option#2: Using apply
DF$eng <- apply(DF[,grep("eng",names(DF))], 1, mean, na.rm = TRUE)
DF
# # A tibble: 4 x 5
#      id  eng1  eng2  eng3   eng
#    <int> <dbl> <dbl> <dbl> <dbl>
# 1     1  50.0    NA  20.0  35.0
# 2     2  NA     100  10.0  55.0
# 3     3  20.0   150  80.0  83.3
# 4     4  30.0   200  40.0  90.0
Sample data:
DF = data_frame(id = 1:4,
                eng1 = c(50, NA, 20, 30), 
                eng2 = c(NA, 100, 150, 200), 
                eng3 = c(20, 10, 80, 40))
Stealing sample data from @MKR, in base R:
DF$eng <- rowMeans(DF[startsWith(names(DF),"eng")], na.rm = TRUE)
# # A tibble: 4 x 5
#      id  eng1  eng2  eng3      eng
#   <int> <dbl> <dbl> <dbl>    <dbl>
# 1     1    50    NA    20 35.00000
# 2     2    NA   100    10 55.00000
# 3     3    20   150    80 83.33333
# 4     4    30   200    40 90.00000
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With