我正在尝试找到最短的dplyr-purr
组合。
我可以简化以下结合了select_if()
和map_df()
的语句吗?
training.set.imputed %>%
select_if(~sum(is.na(.))>0) %>% map_df(~sum(is.na(.)))
我尝试过:
training.set.imputed %>%
select_if(~sum(is.na(.))>0, .funs = ~sum(is.na(.)))
会引发此错误:
错误:
nm
必须为NULL
或长度与x
相同的字符向量
这是什么意思?
有什么想法如何形成.funs
术语?
答案 0 :(得分:3)
.funs
中的select_if
参数需要一个重命名函数,而不是一个变异函数,因此您可以使用它来做类似的事情,但是不能变异变量值:
tibble(blah = 1:2, bleh = 3:4, bluh = c(NA, NA)) %>%
select_if(~ sum(is.na(.x)) > 0, .funs = toupper)
#### OUTPUT ####
# A tibble: 2 x 1
BLUH
<lgl>
1 NA
2 NA
如果您坚持使用purrr和dplyr的组合,那么这可能是您最好的选择(编辑:我刚刚注意到G. Grothendieck给出了这个答案,但是为了方便起见,我还是将其包括在内完整性。):
df %>%
map_df(~ sum(is.na(.))) %>%
select_if(~ . > 0)
#### OUTPUT ####
# A tibble: 1 x 2
b d
<int> <int>
1 4 1
但是,您可以仅使用dplyr的summarize_if
来简化它:
df %>%
summarise_if(anyNA, ~ sum(is.na(.)))
#### OUTPUT ####
# A tibble: 1 x 2
b d
<int> <int>
1 4 1
由于您实际上只是在列求和之后,所以基R可能会提供最简洁的选择:
colSums(is.na(df)) %>%
.[. > 0]
#### OUTPUT ####
b d
4 1
structure(list(a = c(2L, 2L, 5L, 10L, 10L, 18L, 18L, 19L, 11L,
14L, 12L, 10L, 4L, 16L, 5L, 5L, 11L, 2L, 14L, 7L), b = c(10L,
20L, 16L, NA, 6L, 1L, 11L, 12L, 12L, 12L, 8L, NA, NA, 8L, 11L,
19L, 8L, 9L, NA, 19L), c = c(11L, 11L, 20L, 8L, 15L, 4L, 17L,
4L, 4L, 11L, 20L, 11L, 6L, 12L, 17L, 7L, 14L, 18L, 15L, 19L),
d = c(19L, 16L, 17L, 14L, 8L, 19L, 7L, 6L, 6L, 13L, 7L, 19L,
11L, 17L, NA, 10L, 3L, 3L, 3L, 2L), e = c(12L, 17L, 14L,
5L, 8L, 19L, 8L, 3L, 17L, 1L, 2L, 6L, 5L, 17L, 14L, 5L, 8L,
2L, 8L, 2L)), row.names = c(NA, -20L), class = c("tbl_df",
"tbl", "data.frame"))
答案 1 :(得分:0)
我假设您希望每列中的NA数仅保留至少具有1个NA的列。
!)这样可以避免代码重复并且不会产生错误。首先计算每列中的NA数量,然后挑选出大于0的列。
# test input - BOD comes with R
BOD[1,2] <- NA
BOD %>%
map_df(~ sum(is.na(.))) %>%
select_if(~ . > 0)
给予:
# A tibble: 1 x 1
demand
<int>
1 1
2)这首先选择具有至少一个NA的那些列,然后找出这些列中具有相同结果的NA数量:
BOD %>%
select_if(anyNA) %>%
map_df(~ sum(is.na(.)))