我有以下df bhs1
:
structure(list(bhs1_1 = c(NA, 1, NA, 2, 1, 2, 2, 2, 1, 2, 1,
2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2), bhs1_2 = c(NA,
2, NA, 2, 1, 1, 2, 1, 2, 2, 2, 1, 1, 2, 1, 2, 1, 1, 2, 1, 2,
1, 1, 2, 2, 2), bhs1_3 = c(NA, 1, NA, 2, 2, 2, 2, 2, 2, 2, 1,
2, 2, 2, 1, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2), bhs1_4 = c(NA,
2, NA, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1,
1, 1, 2, 1, 1), bhs1_5 = c(NA, 1, NA, 1, 2, 2, 2, 2, 2, 2, 1,
2, 2, 2, 2, 1, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1), bhs1_6 = c(NA,
1, NA, 2, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 2, 2, NA, 2, 1,
2, NA, 1, 1, 2), bhs1_7 = c(NA, 1, NA, 1, 2, 1, 1, 1, 1, 1, 2,
1, 1, 2, 2, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1), bhs1_8 = c(NA,
2, NA, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1,
2, 1, 2, 2, 2), bhs1_9 = c(NA, 1, NA, 2, 1, 1, 1, 1, 2, 1, 2,
1, 1, 1, NA, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2), bhs1_10 = c(NA,
2, NA, 1, 2, 2, 2, 2, 1, 2, 1, 1, NA, 2, 1, 1, 1, 2, 1, 2, 2,
2, 2, 1, 1, 2), bhs1_11 = c(NA, 2, NA, 2, 2, 1, 1, 1, 2, 1, 1,
1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, NA, 2, 2, 1), bhs1_12 = c(NA,
2, NA, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1,
1, 2, 2, 1, 1), bhs1_13 = c(NA, 1, NA, 1, 2, 2, 2, 2, 1, 1, 1,
2, 2, 2, 2, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2), bhs1_14 = c(NA,
2, NA, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1,
1, 1, 2, 2, 1), bhs1_15 = c(NA, 1, NA, 2, 2, 2, 2, 2, 2, 1, 2,
2, 2, 2, 1, 1, 2, 2, 2, NA, 2, 2, 2, 1, 2, 2), bhs1_16 = c(NA,
2, NA, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 1,
1, 2, 2, 2, 2), bhs1_17 = c(NA, 2, NA, 2, 2, 1, 1, 1, 2, 1, 1,
1, 1, 1, 2, 2, 1, NA, 2, 2, 1, 1, 1, 2, 2, 2), bhs1_18 = c(NA,
1, NA, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1,
1, 1, 2, 1, 1), bhs1_19 = c(NA, 1, NA, 2, 1, 2, 2, 2, 1, 2, 2,
2, 2, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 2), bhs1_20 = c(NA,
2, NA, 2, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1,
1, 1, 2, 2, 2)), row.names = c(NA, -26L), class = c("tbl_df",
"tbl", "data.frame"))
bhs1
已通过as_tibble()
。
我对计算新变量bhs1$total
感兴趣,这是变量bhs1_1:bhs1_20
的按比例分配的平均值。按比例分配的原因是,可以将缺失值的观测值与没有缺失值的观测值进行比较。冒着说明显而易见的风险:
NAs
,然后除以18得到一个可比较的平均值,我知道(虽然还不知道如何执行)多重插补,但我不想将此用于此练习。
我尝试过以下代码:
# A tibble: 908 x 21
bhs1_1 bhs1_2 bhs1_3 bhs1_4 bhs1_5 bhs1_6 bhs1_7 bhs1_8 bhs1_9
* <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 NA NA NA NA NA NA NA NA NA
2 1 2 1 2 1 1 1 2 1
3 NA NA NA NA NA NA NA NA NA
4 2 2 2 1 1 2 1 2 2
5 1 1 2 1 2 1 2 2 1
6 2 1 2 1 2 2 1 2 1
7 2 2 2 1 2 2 1 2 1
8 2 1 2 1 2 2 1 2 1
9 1 2 2 1 2 2 1 1 2
10 2 2 2 1 2 1 1 2 1
# ... with 898 more rows, and 12 more variables: bhs1_10 <dbl>,
# bhs1_11 <dbl>, bhs1_12 <dbl>, bhs1_13 <dbl>, bhs1_14 <dbl>,
# bhs1_15 <dbl>, bhs1_16 <dbl>, bhs1_17 <dbl>, bhs1_18 <dbl>,
# bhs1_19 <dbl>, bhs1_20 <dbl>, meanTest <dbl>
哪个按预期工作。但是,当我输入列名而不是列号时,它会失败:
> bhs1$meanTest <- rowMeans(bhs1[,"bhs1_1":"bhs1_20"], na.rm=TRUE)
Error in "bhs1_1":"bhs1_20" : NA/NaN argument
5. check_names_df(j, x)
4. `[.tbl_df`(bhs1, , "bhs1_1":"bhs1_20")
3. bhs1[, "bhs1_1":"bhs1_20"]
2. is.data.frame(x)
1. rowMeans(bhs1[, "bhs1_1":"bhs1_20"], na.rm = TRUE)
我认为使用变量/列名而不是列号要简单得多。是否有一种优雅的方式来编写代码来满足这个用例?如果是这样,有人可以指出我正确的方向和/或提供样品吗?
提前感谢您的考虑和帮助。
答案 0 :(得分:1)
我们需要一个名字载体
nm1 <- paste0("bhs1_", 1:20)
bhs1$meanTest <- rowMeans(bhs1[nm1], na.rm = TRUE)
如果名称没有模式,我们有兴趣在起始名和停止名之间进行分组,那么使用match
获取列索引,获取序列(:
)
nm1 <- Reduce(`:`, match(c("bhs1_1", "bhs1_20"), names(bhs1)))
并在rowMeans
如果我们使用tidyverse
,我们可以指定范围(:
)
bhs1 <- bhs1 %>%
select(bhs1_1:bhs1_20) %>% #can replace with 'nm1'
rowMeans(., na.rm = TRUE) %>%
bind_cols(bhs1, meanTest = .)
如果我们需要在多组列上执行rowMeans
,请使用map2
中的purrr
,将其作为“开始”和“结束”的状态列表传递'{1}}中的列名称,然后通过评估(map2
)后面的select
来获取!!
rowMeans
或者我们可以作为字符串向量传递,然后转换为符号(library(purrr)
map2_df(quos(bhs1_1, bhs1_4), quos(bhs1_5, bhs1_8), ~
bhs1 %>%
select((!! .x) : (!! .y)) %>%
rowMeans(., na.rm = TRUE)) %>%
bind_cols(bhs1, .)
中的sym
)并评估(rlang
)
!!