【问题标题】:Sum NAs across columns using dplyr使用 dplyr 跨列对 NA 求和
【发布时间】:2020-02-22 09:38:07
【问题描述】:

我在 244 列的数据框中有 4 列。我需要对这些列进行求和,这可以通过简单的求和函数来完成。但是,总和没有考虑到 nas。所以当我跑步时:

df <- d%>% 
rowwise() %>% 
mutate(DV = sum(x1, x2, x3, x4, na.rm=TRUE))

我得到 0,当所有值都是 NA 时,我想在 x1[2]、x2[2]、x3[2] 和 x4[2] 中的所有值都为零时得到 NA。我为此挠了 3 个小时,一点也​​不高兴。我确实从互联网上创建(收集)了一个功能,但它仍然无法正常工作:

sum0 <- function(x, ...){if(sum(is.na(x))==4) return(NA_real_) else(sum(x, ..., na.rm=TRUE))} 

df <- d%>% 
rowwise() %>% 
mutate(DV = sum0(x1, x2, x3, x4, na.rm=TRUE))

它不起作用,因为 is.na 值没有正确计算值。我真的被困在这里,任何帮助将不胜感激。

假设数据

 # Create a, b, c, d variables
  a <- c('a1', 'a2', 'a3', 'a4')
  b <- c(10, NA, 30, 40)
  c <- c(2.5, NA, 8, 1)
  d <- c(2.5, NA, 10, 7)
  e <- c(2.5, NA, 10, 7)
  # Join the variables to create a data frame

  df <- data.frame(a, b, c, d, e)
  dfx <- df %>% rowwise() %>% mutate(DV = sum0(c(b,c,d,e)), na.rm = TRUE)

在这里,我希望 DV[2] 中的值为 NA,其余部分正常求和。

【问题讨论】:

  • 请提供带有dput 的数据样本和预期输出。
  • 我提供了一个工作示例,注意有 244 列,所以使用 select(.,-a) 命令并不容易
  • 如果您通过检查原始数据集的所有列值是否为NAs 来替换这些零,通过对每列应用all(is.na(x)) 会怎样?基于 apply(df, 2, function(x) all(is.na(x))) 之类的规则
  • 不幸的是 0 是可接受的响应,所以不能这样做。

标签: r dplyr


【解决方案1】:

你可以这样做:

df %>%
 mutate(DV = rowSums(select(., b:e)))

   a  b   c    d    e   DV
1 a1 10 2.5  2.5  2.5 17.5
2 a2 NA  NA   NA   NA   NA
3 a3 30 8.0 10.0 10.0 58.0
4 a4 40 1.0  7.0  7.0 55.0

如果可能存在只有几个 NA 的行:

df %>%
 mutate(DV = rowSums(select(., b:e), na.rm = TRUE) * NA ^ (rowSums(!is.na(select(., b:e))) == 0))

或者,您也可以这样做:

df %>%
 filter_at(vars(b:e), any_vars(!is.na(.))) %>%
 mutate(DV = rowSums(select(., b:e), na.rm = TRUE)) %>%
 bind_rows(df %>%
            filter_at(vars(b:e), all_vars(is.na(.))))

【讨论】:

  • 不错!从来不知道你可以在 rowSums 函数中使用 select 。我一直只使用rowSums(.[2:5]),但我更喜欢这个。
  • @Annet 你甚至可以使用所有的选择助手作为starts_with()matches() 等:)
猜你喜欢
  • 2016-08-02
  • 2015-05-06
  • 2018-04-13
  • 1970-01-01
  • 1970-01-01
  • 2020-04-04
  • 2023-04-07
  • 2019-07-03
相关资源
最近更新 更多