r-ifelse()与多个列上的all()一起使用



我有这个数据:

library(tidyverse)
data <- tribble(
~a, ~b , ~c , ~d,
0, 0, 0, 0,
1, 1, 0, 0,
0, 1, 0, 0,
0, 0, 0, 1
)

并且想要得到这个输出-如果所有列中都有零,则返回TRUE

# A tibble: 4 x 5
a     b     c     d new  
<dbl> <dbl> <dbl> <dbl> <lgl>
1     0     0     0     0 TRUE 
2     1     1     0     0 FALSE
3     0     1     0     0 FALSE
4     0     0     0     1 FALSE

我试过这个,它有效:

data %>% 
rowwise() %>%
mutate(new = ifelse(all(c(a,b,c,d) == 0) , TRUE, FALSE))

但是如果我有更多的专栏呢?我不想写这样的东西:

data %>% 
rowwise() %>%
mutate(new = ifelse(all(c(a,b,c,d,e,f,.......z) == 0) , TRUE, FALSE))

有更好的写法吗?

注意:我使用的是dplyr 0.8.3

一个基本R选项使用rowSums而不是ifelse

data$new <- rowSums(abs(data))==0

它给出

> data
# A tibble: 4 x 5
a     b     c     d new  
<dbl> <dbl> <dbl> <dbl> <lgl>
1     0     0     0     0 TRUE 
2     1     1     0     0 FALSE
3     0     1     0     0 FALSE
4     0     0     0     1 FALSE

不需要rowwise。使用@d.b的do.call建议:

data %>%
mutate(new = do.call(pmax, .) == 0)
# # A tibble: 4 x 5
#       a     b     c     d new  
#   <dbl> <dbl> <dbl> <dbl> <lgl>
# 1     0     0     0     0 TRUE 
# 2     1     1     0     0 FALSE
# 3     0     1     0     0 FALSE
# 4     0     0     0     1 FALSE

当你需要所有的列时,它就起作用了。如果您需要一个子集,那么您可以使用新的across:

data %>%
mutate(new = do.call(pmax, across(a:d)) == 0)

如果你没有across,试试这个base-R方法来选择一系列列:

data %>%
mutate(new = do.call(pmax, subset(., select = a:d)) == 0)

以下是几种方法。前两个需要最新版本的dplyr,第三个也使用旧版本的dplyr,第四个只使用基本的R。

cur_data()表示当前组。看见https://dplyr.tidyverse.org/reference/context.html三个感叹号!!!来自rlang。它由dplyr导入,并导致其参数的列作为单独的参数传递给pmax。在最后两个解决方案中,apply(data == 0, 1, all)all应用于data == 0的每一行。

data %>% rowwise %>% mutate(new = all(cur_data() == 0)) %>% ungroup
data %>% mutate(new = !pmax(!!!.))
data %>% mutate(new = apply(. == 0, 1, all)) # older versions of dpylr ok
transform(data, new = apply(data == 0, 1, all))  # base R

最新更新