示例数据
df = structure(list(class = structure(c(4L, 1L, 1L, 3L, 2L), .Label = c("apple",
"berry", "grape", "orange"), class = "factor"), value = c(NA,
NA, 1, 1, NA)), .Names = c("class", "value"), row.names = c(NA,
-5L), class = "data.frame")
看起来像
class value
1 orange NA
2 apple NA
3 apple 1
4 grape 1
5 berry NA
仅当组具有另一个非NA值
时,如何在组中删除具有NA的行期望的输出
class value
1 orange NA
2 apple 1
3 grape 1
4 berry NA
使用子集和合并可以分三步完成。我对data.table
方法感兴趣
答案 0 :(得分:5)
试试dplyr
。它产生更简单的代码并且非常快,即使对于大型数据帧也是如此:
df %>%
group_by(class) %>%
filter(!(is.na(value) & sum(!is.na(value)) > 0)) %>%
ungroup
最后的ungroup位只是为了不使用分组数据帧(实际上是dplyr :: tbl)。
答案 1 :(得分:2)
我们可以使用data.table
。转换' data.frame'到' data.table' (setDT(df)
)。按照'类'分组,我们检查if/else
条件是否发生了' NA'价值中的元素'和.SD
library(data.table)
setDT(df)[, if(any(!is.na(value))) .SD[!is.na(value)] else .SD , by = class]
# class value
#1: orange NA
#2: apple 1
#3: grape 1
#4: berry NA
或者我们可以通过略微修改条件将条件从any
更改为all
setDT(df)[, if(all(is.na(value))) .SD else .SD[!is.na(value)], by = class]
# class value
#1: orange NA
#2: apple 1
#3: grape 1
#4: berry NA
或者我们得到行索引(.I
),然后对数据集进行子集化。
indx <- setDT(df)[, if(any(!is.na(value))) .I[!is.na(value)] else .I, class]$V1
df[indx]
答案 2 :(得分:2)
这是一种不同的data.table
方法:
setkey(df,class)
df[!is.na(value)][J(unique(df$class))]
# class value
# 1: apple 1
# 2: berry NA
# 3: grape 1
# 4: orange NA
这要归功于默认操作nomatch=NA
。在控制台中输入?data.table
以获取详细信息。
答案 3 :(得分:1)
您可以使用NA创建所有类的临时变量,然后取出所有NA并添加任何完全删除的类。
df<-setDT(df)
temp<-df[is.na(value),list(class=unique(class), value)]
df<-df[!is.na(value)]
df<-rbindlist(list(df, temp[!class %in% df[,class]]))
rm(temp)