如何将管道中的数据传递给 colSums

时间:2021-03-31 14:49:55

标签: r

我想使用 %>% 通过 colSums 传递数据。事实上,这应该适用于所有的计算。

这是我的例子:

我可以使用以下代码来实现我的目标:

result<- colSums(!is.na(df[ , c("A", "B", "C","D", "RT", "PR", "OTH")]), na.rm = TRUE)

我怎样才能将我的代码改写成这样:

result <- df[ , c("A", "B", "C","D", "RT", "PR", "OTH")] %>%
colSums(!is.na(), na.rm = TRUE)

这些代码不起作用。我收到了错误代码 Error in is.na() : 0 arguments passed to 'is.na' which requires 1。谁能给我一些指导?

谢谢

更新:

示例数据:

df<-structure(list(A = c("A", NA, NA, NA, NA, NA, NA, NA), B = c(NA, 
NA, "B", NA, NA, NA, NA, NA), C = c(NA, "C", NA, NA, NA, NA, 
NA, NA), D = c(NA, NA, NA, "D", "D", NA, NA, NA), RT = c(NA, 
"RT", NA, NA, NA, NA, "RT", NA), PR = c(NA, NA, "PR", NA, NA, 
NA, NA, NA), OTH = c(NA, NA, NA, NA, "OTH", NA, NA, "OTH")), row.names = c(NA, 
-8L), class = c("tbl_df", "tbl", "data.frame"))

3 个答案:

答案 0 :(得分:3)

管道的作用是将管道之前的内容作为管道之后的第一个参数,所以

# What the pipe does
## with pipe
x %>% foo(other_arg)
## equivalent to this:
foo(x, other_arg)

## your version piped:
df[ , c("A", "B", "C","D", "RT", "PR", "OTH")] %>%
  colSums(!is.na(), na.rm = TRUE)

## is interpreted like this:
colSums(df[ , c("A", "B", "C","D", "RT", "PR", "OTH")], !is.na(), na.rm = TRUE)

希望以上内容是有道理的,您会明白为什么会收到关于 is.na() 需要参数的错误。

您可以使用管道,但正如您所注意到的,! 需要特殊处理。 ! 作为前缀具有比 %>% 更高的优先级,因此 R 将尝试评估 ! 结果之前管道进入它。要解决此问题,我们可以将 ! 显式调用为函数,而不是前缀运算符。或者,如果您加载 magrittr 包(%>% 的原始来源),它会为此类情况提供别名,包括 not() 函数,它是 ! 的别名.这些演示如下:

df[ , c("A", "B", "C","D", "RT", "PR", "OTH")] %>%
  is.na() %>%
  `!`() %>%
  colSums(na.rm = TRUE)

library(magrittr)
df[ , c("A", "B", "C","D", "RT", "PR", "OTH")] %>%
  is.na() %>%
  not() %>%
  colSums(na.rm = TRUE)

答案 1 :(得分:1)

我已按以下方式更新了我的代码。我不知道为什么当我否定 is.na 时,我只是无法通过管道获得所需的结果

colSums(!is.na(df[ , c("A", "B", "C","D", "RT", "PR", "OTH")]))

  A   B   C   D  RT  PR OTH 
  1   1   1   2   2   1   2 

只有这样,您才能计算出那些不是 NA 的值。如果你想坚持使用基础 R。

答案 2 :(得分:0)

dplyr 样式是

result <- df[ , c("A", "B", "C","D", "RT", "PR", "OTH")] %>% mutate(across(everything(), ~colSums(!is.na(.), na.rm = TRUE))) 
相关问题