我有这个数据:
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