查找每个id是否有非NA值

3
在长格式的下面数据框中(即每个测量点一行),我想找出哪些人(变量ID)在Var1和Var2上只有NA值,以及哪些人在Var1或Var2上至少有一个非NA值。那些只有NA值的人应该属于Group 0,而那些至少有一个非NA值的人应该属于Group 1。
df <- read.table(text=
"ID       Var1   Var2      
800057    NA    NA               
800057    NA    NA           
800057    NA    NA          
800057    NA    1         
800057    NA    NA 
800119    NA    NA 
800119    NA    NA          
800119    NA    NA      
834011     1    NA
834011     3    NA  
834341    NA    NA
834341    5     NA  
834341    NA    NA   
834341    NA    NA   
834341    3     NA", header=TRUE)

我的结果将会是这样:

df <- read.table(text=
"ID       Var1  Var2  Group    
800057    NA    NA   1            
800057    NA    NA   1        
800057    NA    NA   1       
800057    NA    1    1     
800057    NA    NA   1
800119    NA    NA   0
800119    NA    NA   0       
800119    NA    NA   0   
834011     1    NA   1
834011     3    NA   1
834341    NA    NA   1
834341    5     NA   1   
834341    NA    NA   1
834341    NA    2    1
834341    3     NA   1", header=TRUE)

我想尝试使用group_by(ID)mutate()来创建组变量。

3个回答

4
你可以使用all:
library(dplyr)
df %>%
  group_by(ID) %>%
  mutate(Group = as.integer(!all(is.na(Var1) & is.na(Var2))))

#       ID  Var1  Var2 Group
#    <int> <int> <int> <int>
# 1 800057    NA    NA     1
# 2 800057    NA    NA     1
# 3 800057    NA    NA     1
# 4 800057    NA     1     1
# 5 800057    NA    NA     1
# 6 800119    NA    NA     0
# 7 800119    NA    NA     0
# 8 800119    NA    NA     0
# 9 834011     1    NA     1
#10 834011     3    NA     1
#11 834341    NA    NA     1
#12 834341     5    NA     1
#13 834341    NA    NA     1
#14 834341    NA    NA     1
#15 834341     3    NA     1

或者可以更改最后一行以使用any

mutate(Group = as.integer(any(!is.na(Var1) | !is.na(Var2))))

2
另一个使用 dplyr 的解决方案是比较 NA 行数(is.na())与每个组中的条目数(n())的数量。由于有两个变量,n() 需要乘以二。在比较前加上加号 + 将布尔值转换为数字。
library(dplyr)

df %>% 
  group_by(ID) %>% 
  mutate(group = +(sum(is.na(Var1), is.na(Var2)) < 2 * n()))

可以使用以下代码替换最后一行以避免进行任何比较。

  mutate(group = +(as.logical(sum(is.na(Var1), is.na(Var2)) - 2 * n())))


#> # A tibble: 15 x 4
#> # Groups:   ID [4]
#>        ID  Var1  Var2 group
#>     <int> <int> <int> <int>
#>  1 800057    NA    NA     1
#>  2 800057    NA    NA     1
#>  3 800057    NA    NA     1
#>  4 800057    NA     1     1
#>  5 800057    NA    NA     1
#>  6 800119    NA    NA     0
#>  7 800119    NA    NA     0
#>  8 800119    NA    NA     0
#>  9 834011     1    NA     1
#> 10 834011     3    NA     1
#> 11 834341    NA    NA     1
#> 12 834341     5    NA     1
#> 13 834341    NA    NA     1
#> 14 834341    NA    NA     1
#> 15 834341     3    NA     1

1
您可以在base中使用简单的ifelse()函数。
df$group <- ifelse(is.na(df$Var1) & is.na(df$Var2), 1, 2) 

       ID Var1 Var2 group
1  800057   NA   NA     1
2  800057   NA   NA     1
3  800057   NA   NA     1
4  800057   NA    1     2
5  800057   NA   NA     1
6  800119   NA   NA     1
7  800119   NA   NA     1
8  800119   NA   NA     1
9  834011    1   NA     2
10 834011    3   NA     2
11 834341   NA   NA     1
12 834341    5   NA     2
13 834341   NA   NA     1
14 834341   NA   NA     1
15 834341    3   NA     2

数据:

df <- read.table(text=
"ID       Var1   Var2      
800057    NA    NA               
800057    NA    NA           
800057    NA    NA          
800057    NA    1         
800057    NA    NA 
800119    NA    NA 
800119    NA    NA          
800119    NA    NA      
834011     1    NA
834011     3    NA  
834341    NA    NA
834341    5     NA  
834341    NA    NA   
834341    NA    NA   
834341    3     NA", header=TRUE)

你是否将你的输出与 OP 的期望输出进行比较? - Ronak Shah
我不知道你所说的“OP”是什么,所以我可能没有与之进行比较。 - Pedro Faria
在问题中,给出了预期输出。我的意思是将其与实际输出进行比较,以验证得到的答案是否正确。 - Ronak Shah
嗯,我明白了,是的,我没有进行比较。 - Pedro Faria

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接