R столбец Mutate, представляющий среднее значение для многих других столбцов - PullRequest
0 голосов
/ 23 мая 2018

Я пытаюсь добавить в свой DataFrame столбец, представляющий среднее значение для многих других столбцов (элементов, представляющих одну конструкцию).

В кадре данных есть много других столбцов, но в особенности столбцы eng1, eng2, eng3... engN, где N - большое число, и я хочу взять среднее значение всех столбцов eng * и добавить это значение в качестве нового столбца в мой набор данных.

Я смог сделать это с помощью следующего кода:

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))

Похоже, что требование na.rm = TRUE заставило меня перепрыгнуть через некоторые обручи.

Мой вопрос: есть ли более простые способы сделать это?

Ответы [ 4 ]

0 голосов
/ 23 мая 2018

Данные о краже из @MKR, в базе 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
0 голосов
/ 23 мая 2018

Вы можете использовать pmap_dbl для циклического прохождения каждой строки вашего фрейма данных.Вот пример с некоторыми случайными данными

library(tidyverse)

DF = data_frame(eng1 = c(50, 40, 20, 30), 
                eng2 = c(130, 100, 150, 200), 
                eng3 = c(20, 10, 80, 40))
DF

#> # A tibble: 4 x 3
#>    eng1  eng2  eng3
#>   <dbl> <dbl> <dbl>
#> 1    50   130    20
#> 2    40   100    10
#> 3    20   150    80
#> 4    30   200    40

DF %>% 
  select(starts_with("eng")) %>% 
  mutate(eng = pmap_dbl(., sum))

#> # A tibble: 4 x 4
#>    eng1  eng2  eng3   eng
#>   <dbl> <dbl> <dbl> <dbl>
#> 1    50   130    20   200
#> 2    40   100    10   150
#> 3    20   150    80   250
#> 4    30   200    40   270

# or define a function
sumAll <- function(...) {
  x = c(...)
  sum(x, na.rm = TRUE)
}

DF %>% 
  select(starts_with("eng")) %>% 
  mutate(eng = pmap_dbl(., sumAll))

#> # A tibble: 4 x 4
#>    eng1  eng2  eng3   eng
#>   <dbl> <dbl> <dbl> <dbl>
#> 1    50   130    20   200
#> 2    40   100    10   150
#> 3    20   150    80   250
#> 4    30   200    40   270

, созданными в 2018-05-22 пакетом представлением (v0.2.0).

0 голосов
/ 23 мая 2018

Вы очень в правильном направлении.Вы можете избежать bind_cols с помощью твика в вашем коде.Более того, NA поддерживаются даже в rowMeans.Я изменил пример данных, используемых @Tung, чтобы включить несколько NAs.Решения могут быть следующими:

Вариант № 1: Использование dplyr в подходе, аналогичном 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

Вариант № 2: Использование 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

Пример данных:

DF = data_frame(id = 1:4,
                eng1 = c(50, NA, 20, 30), 
                eng2 = c(NA, 100, 150, 200), 
                eng3 = c(20, 10, 80, 40))
0 голосов
/ 23 мая 2018
# Example data
set.seed(1)
dtf <- as.data.frame(matrix(sample(1:10000), ncol=1000))
nam <- replicate(ncol(dtf), paste(sample(LETTERS, 10, replace=TRUE), collapse=""))
colnames(dtf) <- nam

Я не назвал столбцы 'eng *', но это функционально одинаково.
Усредняться будут только столбцы, имя которых начинается с A.

eng <- rowMeans(dtf[, grep("^A", colnames(dtf))], na.rm=TRUE)
dtf <- cbind(eng, dtf)

summary(dtf)[,1:4]
# #      eng         BRTCBDWVWA     COCSSUQNLA     FIOULRNUXL  
# Min.   :4535   Min.   : 618   Min.   :1764   Min.   : 134  
# 1st Qu.:4780   1st Qu.:2922   1st Qu.:3805   1st Qu.:2254  
# Median :5187   Median :6008   Median :5916   Median :3604  
# Mean   :5107   Mean   :5513   Mean   :5580   Mean   :4174  
# 3rd Qu.:5337   3rd Qu.:8386   3rd Qu.:7557   3rd Qu.:5840  
# Max.   :5739   Max.   :9442   Max.   :9903   Max.   :9329  
...