在 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
。使用 dplyr
和 tidyr
函数:
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],]
假设我有一个纵向数据集如下
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
。使用 dplyr
和 tidyr
函数:
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],]