簡體   English   中英

某些列的行明智 NA 計數 - 按 id 分組

[英]row wise NA count across some columns - grouped by id

我有一個數據框df如下:

輸入

id  na_count    task q1   q2   q3   q4  q5
7   3           a    1    NA   NA   2   NA
7   1           b    1    0    0    NA  0
7   3           c    NA   NA   1    NA  1
9   0           a    1    1    0    2   1
9   1           b    1    0    0    1   NA
9   0           c    1    1    0    1   0
9   1           d    1    0    NA   1   1
3   3           a    1    NA   NA   1   NA
3   1           b    1    1    NA   2   1
1   2           b    1    1    NA   1   NA
1   2           c    1    1    NA   1   NA
1   3           d    NA   NA   1    NA  1
2   4           a    1    NA   NA   NA  NA
2   2           b    1    2    NA   1   NA
2   1           c    1    1    2    NA  2
2   1           d    NA   1    3    3   3
2   0           e    2    2    3    3   4
  1. 我有興趣添加一個二進制列或標志evidence ,它是通過查看每個id數據然后確定該id是否滿足非 NA 值的最小閾值來計算的。

  2. 例如,我將最小非 NA 閾值設置為 10。因此,如果任何id至少有 10 個非 NA 值(多行),那么我想將證據設置為Yes ,否則我想設置證據No

  3. 首選)如果可能,我想使用列na_count中非 NA 值的計數,而不是實際計算列 q1:q5 上的 NA

輸出

對於閾值為 10 非 NA 的示例,我的輸出如下:

id  na_count    task q1   q2   q3   q4  q5  evidence
7   3           a    1    NA   NA   2   NA  no
7   1           b    1    0    0    NA  0   no
7   3           c    NA   NA   1    NA  1   no
9   0           a    1    1    0    2   1   yes
9   1           b    1    0    0    1   NA  yes
9   0           c    1    1    0    1   0   yes
9   1           d    1    0    NA   1   1   yes
3   3           a    1    NA   NA   1   NA  no
3   1           b    1    1    NA   2   1   no
1   2           b    1    1    NA   1   NA  no
1   2           c    1    1    NA   1   NA  no
1   3           d    NA   NA   1    NA  1   no
2   4           a    1    NA   NA   NA  NA  yes
2   2           b    1    2    NA   1   NA  yes
2   1           c    1    1    2    NA  2   yes
2   1           d    NA   1    3    3   3   yes
2   0           e    2    2    3    3   4   yes

部分解決方案

我嘗試了以下方法,但它只計算該 id 的多行中的非 NA 值的行數。

library(dplyr)
df = df %>%
       group_by(id) %>%
           mutate(rows = n())

相關文章

以下帖子是相關的,但沒有解決我的問題如何在 tidyverse 中使 n() 不計算 NA? , 在 group_by() 之后對非缺失值進行 count()並按組計算非 NA 值的數量

輸入()

對於編碼,我還復制了數據幀的dput()

# dput(df)

structure(list(
id = c(7L, 7L, 7L, 9L, 9L, 9L, 9L, 3L, 3L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L), 
na_count = c(3L, 1L, 3L, 0L, 1L, 0L, 1L, 3L, 1L, 2L, 2L, 3L, 4L, 2L, 1L, 1L, 0L), 
task = c("a", "b", "c", "a", "b", "c", "d", "a", "b", "b", "c", "d", "a", "b", "c", "d", "e"), 
q1 = c(1L, 1L, NA, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, NA, 1L, 1L, 1L, NA, 2L), 
q2 = c(NA, 0L, NA, 1L, 0L, 1L, 0L, NA, 1L, 1L, 1L, NA, NA, 2L, 1L, 1L, 2L), 
q3 = c(NA, 0L, 1L, 0L, 0L, 0L, NA, NA, NA, NA, NA, 1L, NA, NA, 2L, 3L, 3L), 
q4 = c(2L, NA, NA, 2L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, NA, NA, 1L, NA, 3L, 3L), 
q5 = c(NA, 0L, 1L, 1L, NA, 0L, 1L, NA, 1L, NA, NA, 1L, NA, NA, 2L, 3L, 4L)), 
row.names = c(NA, -17L), class = "data.frame")

對此的任何幫助將不勝感激,謝謝!

使用tidyverse包的解決方案。 我們可以定義一個輔助函數來計算非 NA 值,嵌套數據幀,將該函數應用於每個 id,然后取消嵌套數據幀。

library(tidyverse)

count_non_na <- function(x, threshold = 10){
  x2 <- x %>%
    dplyr::select(starts_with("q")) %>%
    unlist()
  non_na <- sum(!is.na(x2)) >= threshold
  
  if (non_na){
    result <- "yes"
  } else {
    result <- "no"
  }
  
  return(result)
}

df2 <- df %>%
  group_by(id) %>%
  nest() %>%
  mutate(evidence = map_chr(data, count_non_na)) %>%
  unnest(cols = data) %>%
  ungroup()

df2
# # A tibble: 17 x 9
#       id na_count task     q1    q2    q3    q4    q5 evidence
#    <int>    <int> <chr> <int> <int> <int> <int> <int> <chr>   
#  1     7        3 a         1    NA    NA     2    NA no      
#  2     7        1 b         1     0     0    NA     0 no      
#  3     7        3 c        NA    NA     1    NA     1 no      
#  4     9        0 a         1     1     0     2     1 yes     
#  5     9        1 b         1     0     0     1    NA yes     
#  6     9        0 c         1     1     0     1     0 yes     
#  7     9        1 d         1     0    NA     1     1 yes     
#  8     3        3 a         1    NA    NA     1    NA no      
#  9     3        1 b         1     1    NA     2     1 no      
# 10     1        2 b         1     1    NA     1    NA no      
# 11     1        2 c         1     1    NA     1    NA no      
# 12     1        3 d        NA    NA     1    NA     1 no      
# 13     2        4 a         1    NA    NA    NA    NA yes     
# 14     2        2 b         1     2    NA     1    NA yes     
# 15     2        1 c         1     1     2    NA     2 yes     
# 16     2        1 d        NA     1     3     3     3 yes     
# 17     2        0 e         2     2     3     3     4 yes 

這是另一個想法。 這個方案只需要dplyr包,不需要整個tidyverse包。

df3 <- df %>%
  group_by(id) %>%
  summarize(across(starts_with("q"), .fns = ~sum(!is.na(.)))) %>%
  mutate(Total = rowSums(select(., starts_with("q")))) %>%
  mutate(evidence = ifelse(Total >= 10, "yes", "no")) %>%
  select(id, evidence) %>%
  right_join(df, by = "id") %>%
  relocate(evidence, .after = q5)

df3
# # A tibble: 17 x 9
#       id na_count task     q1    q2    q3    q4    q5 evidence
#    <int>    <int> <chr> <int> <int> <int> <int> <int> <chr>   
#  1     1        2 b         1     1    NA     1    NA no      
#  2     1        2 c         1     1    NA     1    NA no      
#  3     1        3 d        NA    NA     1    NA     1 no      
#  4     2        4 a         1    NA    NA    NA    NA yes     
#  5     2        2 b         1     2    NA     1    NA yes     
#  6     2        1 c         1     1     2    NA     2 yes     
#  7     2        1 d        NA     1     3     3     3 yes     
#  8     2        0 e         2     2     3     3     4 yes     
#  9     3        3 a         1    NA    NA     1    NA no      
# 10     3        1 b         1     1    NA     2     1 no      
# 11     7        3 a         1    NA    NA     2    NA no      
# 12     7        1 b         1     0     0    NA     0 no      
# 13     7        3 c        NA    NA     1    NA     1 no      
# 14     9        0 a         1     1     0     2     1 yes     
# 15     9        1 b         1     0     0     1    NA yes     
# 16     9        0 c         1     1     0     1     0 yes     
# 17     9        1 d         1     0    NA     1     1 yes
library(tidyverse)

threshold = 10

df %>% group_by(id) %>%
  mutate(evidence = ifelse(n()*5 - sum(na_count) >= threshold, "yes", "no"))

5 來自您擁有的列數 q1:q5。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM