统计每列非零元素的个数——管道友好

Count the number of non-zero elements of each column- Piping Friendly

我是一名使用 R 的行为生态学家。我正在尝试计算多个列中的非零元素。通常,当我这样做时,我已经成功地将 colSums 与 !=0 运算符结合使用,正如此处和其他地方的许多帖子所建议的那样,即 (Count the number of non-zero elements of each column).

但是在这种特殊情况下,我真的更喜欢使用管道 - 因为这只是构建更大数据框的一个步骤 - 而且我似乎无法使用 !=0 获得 colSums 来很好地与管道。有没有办法让它工作,或者是否有更优雅的替代方法来计算生活在 tidy-verse 某处的列中的非零值?

我在下面放了一些示例代码来演示。非常感谢!

'''

#make example dataframe
example<- as.data.frame(matrix(sample(c(0,0,0,100),size=70,replace=T),ncol=7))
example<-cbind(Indentifier1="character a",Indentifier2="character b", example)
example


#works great but isn't piping friendly:
colSums(example[-c(1:2)] !=0)  

#Runs but because it lacks the !=0 operator it gives sums not counts of non-zero elements, can't figure out how to employ !=0:
example %>% select(-c(1:2)) %>% colSums() 


#gives me counts of all values, not sure how to call just non-zero values:
example %>% summarise(across(where(is.numeric), length))
 

'''

example %>% summarise(across(where(is.numeric), ~sum(. != 0)))

如果您想完全 magrittr,请阅读 ?alias

library(magrittr)
example %>% 
  extract(-c(1, 2)) %>%
  equals(0) %>%
  not() %>%
  colSums()
# V1 V2 V3 V4 V5 V6 V7 
# 2  3  1  4  3  4  1 

数据

set.seed(42)
example<- as.data.frame(matrix(sample(c(0,0,0,100),size=70,replace=T),ncol=7))
example<-cbind(Indentifier1="character a",Indentifier2="character b", example)
example


#works great but isn't piping friendly:
colSums(example[-c(1:2)] !=0) 
# V1 V2 V3 V4 V5 V6 V7 
# 2  3  1  4  3  4  1 

获取您要计算的逻辑矩阵,并将其通过管道传输到 colSums()

(example |> select(-(1:2)) != 0) |> 
    colSums()

当然这很棘手,因为它依赖于强制 example |> select(-(1:2)) 在与 0 比较之前进行评估的隐式操作顺序规则,以及评估 () 所需的显式分组管道传输到 colSums().

之前的不等式

您仍然可以使用带有基本 R 代码的管道。例如,您可以这样做:

example %>%
  .[-c(1:2)] %>%
  replace(., . != 0, 1) %>%
  colSums()

#V1 V2 V3 V4 V5 V6 V7 
# 2  3  1  2  4  1  1 

只需使用 base R (>= 4.1) 即可

example |>
  subset(select=-(1:2)) |>
  {\(.) colSums(. != 0)}()
# V1 V2 V3 V4 V5 V6 V7 
#  4  4  3  3  3  2  2