我正在尝试在我的 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))
Run Code Online (Sandbox Code Playgroud)
似乎有 na.rm=TRUE 要求迫使我跳过一些箍。
我的问题是是否有更直接的方法来做到这一点?
你的方向非常正确。您可以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
Run Code Online (Sandbox Code Playgroud)
选项#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
Run Code Online (Sandbox Code Playgroud)
样本数据:
DF = data_frame(id = 1:4,
eng1 = c(50, NA, 20, 30),
eng2 = c(NA, 100, 150, 200),
eng3 = c(20, 10, 80, 40))
Run Code Online (Sandbox Code Playgroud)
从 @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
Run Code Online (Sandbox Code Playgroud)