繁体   English   中英

R:为一组列返回只有 1 个非 NA 值的行

[英]R: Return rows with only 1 non-NA value for a set of columns

假设我有一个包含以下数据的 data.table:

colA  colB  colC  result
1     2     3     231
1     NA    2     123
NA    3     NA    345
11    NA    NA    754

我将如何使用dplyrmagrittr只选择以下行:

colA  colB  colC result
NA    3     NA   345
11    NA    NA   754

选择标准是:AC 列只有 1 个非 NA 值(即colA, colB, ColC

我一直找不到类似的问题; 猜测这是一个奇怪的情况。

一个基本的 R 选项是

df[apply(df, 1, function(x) sum(!is.na(x)) == 1), ]
#  colA colB colC
#3   NA    3   NA
#4   11   NA   NA

dplyr选项是

df %>% filter(rowSums(!is.na(.)) == 1)

更新

为了回应你的评论,你可以做

df[apply(df[, -ncol(df)], 1, function(x) sum(!is.na(x)) == 1), ]
#  colA colB colC result
#3   NA    3   NA    345
#4   11   NA   NA    754

或在dplyr相同

df %>% filter(rowSums(!is.na(.[-length(.)])) == 1)

这假设最后一列是您要忽略的列。


样本数据

df <-read.table(text = "colA  colB  colC
1     2     3
1     NA    2
NA    3     NA
11    NA    NA", header = T)

用于更新的示例数据

df <- read.table(text =
"colA  colB  colC  result
1     2     3     231
1     NA    2     123
NA    3     NA    345
11    NA    NA    754
", header = T)

另一种选择是用map filter

library(dplyr)
library(purrr)
df %>% 
    filter(map(select(., starts_with('col')), ~ !is.na(.)) %>% 
              reduce(`+`) == 1)
#    colA colB colC result
#1   NA    3   NA    345
#2   11   NA   NA    754

或者另一种选择是使用transmute_at

df %>% 
   transmute_at(vars(starts_with('col')), ~ !is.na(.)) %>% 
   reduce(`+`) %>%
   magrittr::equals(1) %>% filter(df, .)
#  colA colB colC result
#1   NA    3   NA    345
#2   11   NA   NA    754

数据

df <- structure(list(colA = c(1L, 1L, NA, 11L), colB = c(2L, NA, 3L, 
NA), colC = c(3L, 2L, NA, NA), result = c(231L, 123L, 345L, 754L
)), class = "data.frame", row.names = c(NA, -4L))

我认为这可以通过filter_at实现,但我无法使其工作。 这是使用filterpmap_lgl一种尝试,您可以在其中指定select的列范围或通过它们的位置指定或使用其他 tidyselect 辅助变量。

library(dplyr)
library(purrr)

df %>%
  filter(pmap_lgl(select(., colA:colC), ~sum(!is.na(c(...))) == 1))

 #  colA colB colC result
#1   NA    3   NA    345
#2   11   NA   NA    754

数据

df <- structure(list(colA = c(1L, 1L, NA, 11L), colB = c(2L, NA, 3L, 
NA), colC = c(3L, 2L, NA, NA), result = c(231L, 123L, 345L, 754L
)), class = "data.frame", row.names = c(NA, -4L))

暂无
暂无

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

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