如何填写R

时间:2018-11-19 23:56:43

标签: r merge na

我有一个表,其中包含列idcolAcolB。数据包含重复的id列,其中对于某些行,colAcolB为空,但其重复的id具有有效值。我想清除数据,以便删除重复项,但有完整的数据。例如我的数据看起来像

id | colA | colB
 1     NA    X
 1      Y    X
 2      Z    NA
 2      Z    Y
 3      Z    Y
 3      Z    Y
 4     NA    NA
 4     NA    NA

我希望我的数据框看起来像

id | colA | colB
1     Y      X
2     Z      Y
3     Z      Y
4     NA     NA

我通常使用ifelse语句替换丢失的值,但是对于在重复id的情况下如何使用它,我感到困惑。

3 个答案:

答案 0 :(得分:4)

首先添加一列,以告知每行中有NA个。然后使用dplyr,先删除重复的行,然后为每个id保留值最少的行-

df$test <- rowSums(is.na(df))

df %>% 
  filter(!duplicated(.)) %>% 
  arrange(id, test) %>% 
  group_by(id) %>% 
  filter(row_number() == 1) %>% 
  ungroup() %>% 
  select(-test)

# A tibble: 4 x 3
     id colA  colB 
  <int> <chr> <chr>
1     1 y     x    
2     2 z     y    
3     3 z     y    
4     4 <NA>  <NA> 

编辑: 实际上,无需先删除重复项。仅使每个ID的缺失值最少的行也应该起作用-

df$test <- rowSums(is.na(df))

df %>% 
  arrange(id, test) %>% 
  group_by(id) %>% 
  filter(row_number() == 1) %>% 
  ungroup() %>% 
  select(-test)

数据-

df <- data.frame(
  id = c(rep(seq(1:4), each =2)), colA = c(NA, "y", "z", "z", "z", "z", NA, NA), 
  colB = c("x", "x", NA, "y", "y", "y", NA, NA), stringsAsFactors = F)

答案 1 :(得分:2)

这个答案很大程度上取决于您的实际数据在结构上与示例数据相似。

您的数据:

df1 <- structure(list(id = c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L), 
                      colA = c(NA, "Y", "Z", "Z", "Z", "Z", NA, NA), 
                      colB = c("X", "X", NA, "Y", "Y", "Y", NA, NA)), 
                      class = "data.frame", 
                      row.names = c(NA, -8L))

假设像您的示例一样,每个id出现两次,并且其中一个观察值是NA,这是该id的第一个观察值,那么它起作用:

library(dplyr)
library(tidyr)

df1 %>% 
  group_by(id) %>% 
  fill(colA, colB, .direction = "up") %>%  
  ungroup() %>% 
  distinct()

# A tibble: 4 x 3
     id colA  colB 
  <int> <chr> <chr>
1     1 Y     X    
2     2 Z     Y    
3     3 Z     Y    
4     4 NA    NA 

如果id的第二个观测值可以是NA,则可以尝试在第一个观测值之后添加第二个fill,但这一次填充:

df1 %>% 
  group_by(id) %>% 
  fill(colA, colB, .direction = "up") %>%  
  fill(colA, colB, .direction = "down") %>%  
  ungroup() %>% 
  distinct()

答案 2 :(得分:1)

创建数据框-如果您发布代码以制作示例数据,这会有所帮助

df <- data.frame(id = c(rep(seq(1:4), each =2)), colA = c(NA, "y", "z", "z", "z", "z", NA, NA), colB = c("x", "x", NA, "y", "y", "y", NA, NA))

使用单个NA删除行

for(i in 1:nrow(df)){

  if(is.na(df[i,]$colA) & !is.na(df[i,]$colB) | !is.na(df[i,]$colA) & is.na(df[i,]$colB)){

df <- df[-i,]

  }
}

删除剩余的重复项(即,不重复的NA行)

df  <- df[!duplicated(df), ]

输出

df

这样做可能是一种计算效率更高的方法,但这应该可行。