如何获取行的ID,这些行在某些列中相同但在其他列中具有NA

时间:2017-09-07 04:38:08

标签: r

我有一些包含某些行的数据框,在某些列中是相同的,并且应该相同,而是填充row(at point: NSPoint) -> Int

示例:

NA

实际上,这是一个很大的数据集,并且不仅仅有两个值。

我想获得行 ID NAME SURNAME value1 value2 1 1 Luke Skywalker 1 3 2 2 Luke Skywalker NA NA 3 3 Luke Skywalker NA NA 4 6 Han Solo NA NA 5 7 Han Solo 5 5 6 8 Han Solo 4 NA 的向量,它们具有相同的IDName,但在列中有Surname个值,其中列具有相同名称和姓氏具有实际值。如果存在混合数据的情况(如NA所示),我想获得仅Han数据的ID行,除非有一个包含值的完整行,与不完整行中的那一行相同,那么我还想得到不完整行的NA

所以我的例子的回报是ID

编辑:正如问题中所提到的,姓名和姓氏很重要,因为我只想获得c(2,3,6)当且仅当有完整或更完整的行时为该名称姓氏组合。变量实际上是测试的结果,每年应该只发生一次(在我的df中,我也会按测试日期分组,我在这里跳过,因为分组变量应该对解决方案没有影响,就我而言知道)。

4 个答案:

答案 0 :(得分:1)

这是获取行ID的向量的示例,其具有相同的Nameand Surname,但在列中具有NA值" &安培; "只获取行的ID,只有NAdata":

df <- read.table(header = TRUE, text = " ID   NAME   SURNAME      value1     value2
1     1  Luke Skywalker            1         3 
             2     2  Luke Skywalker            NA        NA
             3     3  Luke Skywalker            NA        NA
             4     6   Han      Solo            NA        NA
             5     7   Han      Solo            5         5 
             6     8   Han      Solo            4         NA ")

df[apply(df[ , c("value1", "value2")], 1, function(x) all(is.na(x))), ]

答案 1 :(得分:1)

另一种选择是对使用仅具有“值”列的数据集子集创建的逻辑矩阵使用rowSums。它是矢量化的,应该适用于数据集中的任意数量的“值”列

df[!rowSums(!is.na(df[grep("value", names(df))])),]
#  ID NAME   SURNAME value1 value2
#2  2 Luke Skywalker     NA     NA
#3  3 Luke Skywalker     NA     NA
#4  6  Han      Solo     NA     NA

答案 2 :(得分:0)

使用dplyr的解决方案。

library(dplyr)

df %>% filter_at(vars(-ID, -NAME, -SURNAME), all_vars(is.na(.)))

  ID NAME   SURNAME value1 value2
1  2 Luke Skywalker     NA     NA
2  3 Luke Skywalker     NA     NA
3  6  Han      Solo     NA     NA

filter_at是一种过滤多列条件的方法。我们可以使用vars(...)来选择我们想要的列。在上面的示例中,vars(-ID, -NAME, -SURNAME)表示过滤条件未应用于IDNAMESURNAME列。因为您说您需要过滤两列以上的条件,所以我想演示指定过滤列的其他方法。以下代码以及指定列的其他方法也可以使用。

# Select columns to begin with "value"
df %>% filter_at(vars(starts_with("value")), all_vars(is.na(.)))

# Select columns to contain "value"
df %>% filter_at(vars(contains("value")), all_vars(is.na(.)))

# Select columns to match "value" using regular expression
df %>% filter_at(vars(matches("value")), all_vars(is.na(.)))

# Select columns by column index numbers, not using the first three columns
df %>% filter_at(vars(-1:-3), all_vars(is.na(.)))

# Select columns by column index numbers, starting the fourth column to the end
df %>% filter_at(vars(4:ncol(.)), all_vars(is.na(.)))

all_vars(is.na(.))表示指定的所有列都需要满足过滤条件(is.na(.) == TRUE)。

数据

df <- read.table(header = TRUE, text = " ID   NAME   SURNAME      value1     value2
1     1  Luke Skywalker            1         3 
                 2     2  Luke Skywalker            NA        NA
                 3     3  Luke Skywalker            NA        NA
                 4     6   Han      Solo            NA        NA
                 5     7   Han      Solo            5         5 
                 6     8   Han      Solo            4         NA ")

答案 3 :(得分:0)

如果我理解正确:)

df <- read.table(header = TRUE, text = " ID   NAME   SURNAME      value1     value2
1     1  Luke Skywalker            1         3 
             2     2  Luke Skywalker            NA        NA
             3     3  Luke Skywalker            NA        NA
             4     6   Han      Solo            NA        NA
             5     7   Han      Solo            5         5 
             6     8   Han      Solo            4         NA ")

all_or_some_na  <- which(unname(apply(df[4:ncol(df)],1,anyNA)))
all_na          <- which(unname(apply(df[4:ncol(df)],1,function(x) all(is.na(x)))))
some_na         <- setdiff(all_or_some_na,all_na)
complete_rows   <- setdiff(1:nrow(df),all_or_some_na)