假设我编写以下代码来生成数据帧:
name <- c("Joe","John","Susie","Mack","Mo","Curly","Jim")
age <- c(1,2,3,NaN,4,5,NaN)
DOB <- c(10000, 12000, 16000, NaN, 18000, 20000, 22000)
DOB <- as.Date(DOB, origin = "1960-01-01")
trt <- c(0, 1, 1, 2, 2, 1, 1)
df <- data.frame(name, age, DOB, trt)
看起来像这样:
name age DOB trt
1 Joe 1 1987-05-19 0
2 John 2 1992-11-08 1
3 Susie 3 2003-10-22 1
4 Mack NaN <NA> 2
5 Mo 4 2009-04-13 2
6 Curly 5 2014-10-04 1
7 Jim NaN 2020-03-26 1
如何删除年龄和DOB都缺少该行的值的行?例如,我希望新数据框(df2)看起来像这样:
name age DOB trt
1 Joe 1 1987-05-19 0
2 John 2 1992-11-08 1
3 Susie 3 2003-10-22 1
5 Mo 4 2009-04-13 2
6 Curly 5 2014-10-04 1
7 Jim NaN 2020-03-26 1
我尝试过以下代码,但删除了太多行:
df2 <- df[!(is.na(df$age)) & !(is.na(df$DOB)), ]
在SAS中,我会写
在DATA步骤中WHERE missing(age) ge 1 AND missing(DOB) ge 1
,但显然R具有不同的语法。
提前致谢!
答案 0 :(得分:1)
如果要删除两列(年龄和DOB)的NA大于1的行(这在数学上意味着在这种情况下只能有2个NA),您可以这样做:
df[!is.na(df$age) | !is.na(df$DOB),]
这意味着两个列或其中一列应该不 NA,或
df[rowSums(is.na(df[2:3])) < 2L,]
这意味着第2列和第3列中的NA之和应小于2(因此,1或0)或非常相似:
df[rowSums(is.na(df[c("age", "DOB")])) < 2L,]
当然还有其他选项,比如@rawr在评论中提供的内容。
为了更好地理解子集,请检查:
rowSums(is.na(df[2:3]))
#[1] 0 0 0 2 0 0 1
rowSums(is.na(df[2:3])) < 2L
#[1] TRUE TRUE TRUE FALSE TRUE TRUE TRUE
答案 1 :(得分:1)
也许这会更容易:
require(tidyverse)
df <- drop_na(df, c("age", "DOB"))
答案 2 :(得分:0)
你非常接近
df[!(is.na(df$age) & is.na(df$DOB)), ]
或
df[!is.na(df$age) | !is.na(df$DOB), ]