在 R studio 中删除多行的不完整案例

Deleting incomplete cases across multiple rows in R studio

假设我有一个纵向数据集如下

ID <- c(1, 1, 2, 2, 3, 3, 4, 4)
time <- c(1, 2, 1, 2, 1, 2, 1, 2)
value <- c(7, 5, 9, 2, NA, 3, 7, NA)

mydata <- data.frame(ID, time, value)

  ID time value
1  1    1     7
2  1    2     5
3  2    1     9
4  2    2     2
5  3    1    NA
6  3    2     3
7  4    1     7
8  4    2    NA

在这个数据集中,我们有 4 个案例在两个时间点(假设治疗前和 post 治疗)

我想做的是设置标准以删除 两个时间点 未完成的任何案例。在此示例中,我想删除 ID3(缺少时间点 1)和 ID4(缺少时间点 2)。如下图:

  ID time value
1  1    1     7
2  1    2     5
3  2    1     9
4  2    2     2

我运气不好。我试过 complete.cases() 或 which() 的变体都无济于事

我还是 R 的新手,如果有人能帮助我,我将不胜感激

编辑:感谢 Ronak 回答我的问题。反思我的真实数据,我遇到了第二个问题。我的实际数据更多地反映在下面:

ID <- c(1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8)
time <- c(1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1)
value <- c(7, 5, 9, 2, NA, 3, 7, NA, 8, 9, 7, 6)

mydata <- data.frame(ID, time, value)



    ID time value
1   1    1     7
2   1    2     5
3   2    1     9
4   2    2     2
5   3    1    NA
6   3    2     3
7   4    1     7
8   4    2    NA
9   5    1     8
10  6    1     9
11  7    1     7
12  8    1     6

想删除案例 5、6、7 和 8。这些 ID 有时间 1 的条目,但没有时间 2。希望这是有道理的

感谢堆

查看更新后的答案

# Eliminates ID cases with NA
mydata = mydata[!mydata$ID %in% mydata[!complete.cases(mydata) ,]$ID, ]

library(plyr)
# counts all the IDs
cnt = count(mydata, "ID")
# Eliminates any ID that doesn't have 2 observations
mydata[mydata$ID %in% cnt[cnt$freq == 2, ]$ID, ]

  ID time value
1  1    1     7
2  1    2     5
3  2    1     9
4  2    2     2

如果将数据切换为宽格式(每个时间点都表示为自己的列),则可以使用 na.omit。使用 dplyrtidyr 函数:

library(dplyr)    
mydata <- mydata %>%
tidyr::spread(key=time, value=value) %>% # reformat to wide
na.omit() %>% # delete cases with missingness on any variable (i.e. any time point)
tidyr::gather(key="time", value="value", -ID) # put it back in long format

> mydata
  ID time value
1  1    1     7
2  2    1     9
3  1    2     5
4  2    2     2

请注意,这将起作用(它将仅保留时间 1 和时间 2 的完整数据的案例),即使您缺少时间点但数据中没有明确的 NA,如下所示:

> mydata
   ID time value
1   1    1     7
2   1    2     5
3   2    1     9
4   2    2     2
5   3    1    NA
6   3    2     3
7   4    1     7
8   4    2    NA
9   5    1     8
10  6    1     9
11  7    1     7
12  8    1     6

您可以使用 sqldf 轻松做到这一点。

library(sqldf)    
sqldf(' select * from (select ID, count(*) as cnt from mydata where value is not null group by id having cnt >1 ) t1 inner join mydata t2 on t1.ID=t2.ID')

您会 select 那些计数大于 1 且其值中没有 NA 的 ID,然后用原始数据重新加入。

@Ronak 已经提供

mydata[!mydata$ID %in% mydata$ID[is.na(mydata$value)], ]

对于第二部分,您可以对每个 ID 进行分组并按其频率进行过滤

k2 <- data.frame(table(mydata$ID))

k2$Var1[k2$Freq > 1]

然后做类似

的事情

mydata[mydata$ID %in% k2$Var1[k2$Freq > 1],]