计算每个区域组具有特定值的列数

时间:2021-07-28 10:34:56

标签: r dataframe dplyr sum

我想知道对于每个唯一的列 df[,3:length(df)] 组有多少列 (ID) 不全为零。结果将存储为新的 df。

> df
ID     INDV     tra1   tr2   tr3  tra2   tr15   tr1b  
ENS777   1       1.2    0     0   1.6    3.3    0
ENS777   2       1.2    0     0   0.0    3.3    0
ENS777   3       1.2    0     0   0.0    3.3    0
ENS777   4       1.2    0     0   1.6    3.3    0
ENS999   1        0     0     0    0      0     0
ENS999   2        0     0     0    0      0     0
ENS999   3        0     0     0    0      0     0
ENS999   4        0     0     0    0      0     0
ENS888   1       1.2    0     0   1.6    3.3    0
ENS888   2       1.2    0     0   1.6    3.3   1.2
ENS888   3       1.2    0     0   1.6    3.3    0
ENS888   4       1.2    0     0   1.6    3.3    0 

 > df_out
ID      non_zero      
ENS777    3 
ENS999    0
ENS888    4

3 个答案:

答案 0 :(得分:1)

您可以使用 agregate 获取非零行的 max。这些行由 rowSums(df[3:ncol(df)] > 0),

找到
setNames(aggregate(rowSums(df[3:ncol(df)] > 0) ~ ID, df, max), c('ID', 'non_zeros'))

#      ID non_zeros
#1 ENS777         3
#2 ENS888         4
#3 ENS999         0

答案 1 :(得分:1)

tidyverse

library(dplyr)
df %>% 
  group_by(ID) %>% 
  summarise(across(starts_with("tr"), ~sum(.x) != 0)) %>% 
  transmute(ID, non_zero = rowSums(select(., starts_with("tr"))))

# A tibble: 3 x 2
  ID     non_zero
  <chr>     <dbl>
1 ENS777        3
2 ENS888        4
3 ENS999        0

data.table

library(data.table)
library(magrittr)
COLS <- grep("^tr", names(df), value = TRUE)
setDT(df)[, lapply(.SD, function(x) sum(x) != 0), by = ID, .SDcols = COLS] %>% 
  .[, list(ID, non_zero = Reduce(`+`, .SD)), .SDcols=COLS] %>% 
  .[]

setDT(df)[, lapply(.SD, function(x) sum(x) != 0), by = ID, .SDcols = COLS] %>% 
  .[, list(ID, non_zero = rowSums(.SD)), .SDcols=COLS] %>% 
  .[]
       ID non_zero
1: ENS777        3
2: ENS999        0
3: ENS888        4

答案 2 :(得分:1)

我们可以使用all

library(dplyr)

df %>% 
    group_by(ID) %>% 
    summarise(across(starts_with("tr"), ~all(. == 0))) %>% 
    rowwise() %>%
    mutate(non_zero = sum(across(starts_with("tr")) == FALSE)) %>% 
    select(ID, non_zero)

输出:

  ID     non_zero
  <chr>     <int>
1 ENS777        3
2 ENS888        4
3 ENS999        0