繁体   English   中英

R:计算具有匹配项的列子集的逻辑或

[英]R: Compute logical OR over subset of columns with matches

我有这个数据框:

df <- tibble(id = c(1, 2, 3), c_1 = c(T, T, F), c_2 = c(F, F, T)) %>% group_by(id)
# A tibble: 3 x 3
     id c_1   c_2  
  <dbl> <lgl> <lgl>
1     1 TRUE  FALSE
2     2 TRUE  FALSE
3     3 FALSE TRUE 

我现在想计算以c_开头的列的行逻辑 OR 我试过

df %>% mutate(valid = sum(select(matches("^c_")) == 0))

但是我得到

`matches()` must be used within a *selecting* function.

我该如何解决这个问题?

library(dplyr)

df <- tibble(id = c(1, 2, 3), c_1 = c(T, T, F), c_2 = c(F, F, T))

df %>% 
  rowwise() %>% 
  mutate(
    valid = any(c_across(starts_with("c_")))
  ) %>% 
  ungroup()

#> # A tibble: 3 × 4
#>      id c_1   c_2   valid
#>   <dbl> <lgl> <lgl> <lgl>
#> 1     1 TRUE  FALSE TRUE 
#> 2     2 TRUE  FALSE TRUE 
#> 3     3 FALSE TRUE  TRUE

reprex 包于 2022-07-11 创建 (v2.0.1)

更新:为什么需要 tibble():

没有as_tibble()或 tibble( tibble()data.frame()它将无法工作:

你的桌子:

> class(df)
[1] "grouped_df" "tbl_df"     "tbl"        "data.frame"
  • 没有as_tibble()或 tibble( tibble()data.frame() -> 将无法工作:
>df %>%
  mutate(valid = ifelse(rowSums(select(., contains("c_")))==1, TRUE, FALSE))

Adding missing grouping variables: `id`
Error in `mutate()`:
! Problem while computing `valid = ifelse(rowSums(select(.,
  contains("c_"))) == 1, TRUE, FALSE)`.
x `valid` must be size 1, not 3.
i The error occurred in group 1: id = 1.
  • 使用as_tibble()或 tibble( tibble()data.frame() -> 它将起作用:
df %>% 
  data.frame() %>% 
  mutate(valid = ifelse(rowSums(select(., contains("c_")))==1, TRUE, FALSE))

#or

df %>% 
  tibble() %>% 
  mutate(valid = ifelse(rowSums(select(., contains("c_")))==1, TRUE, FALSE))

第一个答案:如果我们想使用 select: 这是一个开箱即用的方法:

library(tibble)
library(dplyr)

df %>% 
  as_tibble() %>% 
  mutate(valid = ifelse(rowSums(.[2:3])==1, TRUE, FALSE))

或者

library(tibble)
library(dplyr)

df %>% 
  as_tibble() %>% 
  mutate(valid = ifelse(rowSums(select(., contains("c_")))==1, TRUE, FALSE))
# A tibble: 3 x 4
     id c_1   c_2   valid
  <dbl> <lgl> <lgl> <lgl>
1     1 TRUE  FALSE TRUE 
2     2 TRUE  FALSE TRUE 
3     3 FALSE TRUE  TRUE 

我们可以直接使用if_any而不用 rowwise

library(dplyr)
df %>%
   mutate(valid = if_any(starts_with('c_')))
# A tibble: 3 × 4
     id c_1   c_2   valid
  <dbl> <lgl> <lgl> <lgl>
1     1 TRUE  FALSE TRUE 
2     2 TRUE  FALSE TRUE 
3     3 FALSE TRUE  TRUE 

数据

df <- tibble(id = c(1, 2, 3), c_1 = c(TRUE, TRUE, FALSE),
 c_2 = c(FALSE, FALSE, TRUE))

使用grepl base R选项:

library(dplyr) # For tibble
df <- tibble(id = c(1, 2, 3), c_1 = c(T, T, F), c_2 = c(F, F, T)) %>% group_by(id)
df$valid <- apply(df, 1, function(x) any(x %in% grepl("c_" , names(x))))
df
#> # A tibble: 3 × 4
#> # Groups:   id [3]
#>      id c_1   c_2   valid
#>   <dbl> <lgl> <lgl> <lgl>
#> 1     1 TRUE  FALSE TRUE 
#> 2     2 TRUE  FALSE TRUE 
#> 3     3 FALSE TRUE  TRUE

reprex 包于 2022-07-11 创建 (v2.0.1)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM