在R中:如果缺少另一行的值,则替换行的值

时间:2014-10-02 13:25:28

标签: r missing-data

我对R比较新,可能解决这个问题的方法很简单。

我有一个如下所示的数据框:

id1    id2    v1    v2    v3    ...    v100
  A      X     1    NA    NA    ...       1
  B      Y     1     3     4    ...       1
  C      X     1     3     4    ...       1
  D      X     1     3     4    ...       1
  E      Y     1     3     4    ...       1
  A      X    NA     3     4    ...      NA 

我想做的是'合并'具有相同id(id1和id2)的两个观察到一个观察。观察的缺失值应该用另一个观察值替换。

例如,在上面的数据框中,这些是观察1'和观察6'结果看起来应该是这样的:

id1    id2    v1    v2    v3    ...    v100
  A      X     1     3     4    ...       1
  B      Y     1     3     4    ...       1
  C      X     1     3     4    ...       1
  D      X     1     3     4    ...       1
  E      Y     1     3     4    ...       1

目前我正在使用循环,我知道它非常慢,可能不是最好的解决方案。我有超过1000个观测值,大约100个重复观测值和几千个变量。如果有人能提出如何加快速度的想法,我会非常高兴。

非常感谢提前!

编辑:03/10/2014

非常感谢所有有用的评论! David Armstrong的答案就是我想要的!非常感谢你!

我很抱歉在我的第一篇文章中不够精确,所以这里有一些规范。

使用相同ID的观察可以在数据集中多次出现,而不仅仅是两次。

此外,在所有那些相同的观察中,只有一个观察将具有每个变量的非缺失值(如果全部)。也可能是因为缺少变量的所有观察结果,但是两个观察结果都具有非缺失值的情况永远不会是这种情况。以下示例可能会使事情更加清晰。

id1    id2    v1    v2    v3    v4    v5    v6    v7
  A      X     6     9     3     1     2     1     1
  B      X     2     2     1     4     2     3     3
  C      X     1     6     7     1     3     4     5
  D      X     4     2     9     2     3     6     2
  E      X    NA     3    NA    NA    NA    NA    NA
  E      X    NA    NA     4    NA    NA    NA    NA
  E      X    NA    NA    NA     3    NA    NA    NA
  E      X    NA    NA    NA    NA     6    NA    NA
  E      X    NA    NA    NA    NA    NA     4    NA
  E      X    NA    NA    NA    NA    NA    NA     1

我希望得到的结果是:

id1    id2    v1    v2    v3    v4    v5    v6    v7
  A      X     6     9     3     1     2     1     1
  B      X     2     2     1     4     2     3     3
  C      X     1     6     7     1     3     4     5
  D      X     4     2     9     2     3     6     2
  E      X    NA     3     4     3     6     4     1

我希望这会有所帮助。

非常感谢!

3 个答案:

答案 0 :(得分:2)

另外,也许

library(data.table)
setDT(df)[, lapply(.SD, na.omit), by = list(id1, id2)]
#    id1 id2 v1 v2 v3 v100
# 1:   A   X  1  3  4    1
# 2:   B   Y  1  3  4    1
# 3:   C   X  1  3  4    1
# 4:   D   X  1  3  4    1
# 5:   E   Y  1  3  4    1

如果我们不能总是假设缺少值(如@Rolands评论中提到的那样),您可以添加unique(如果您总是只想要一对)。像

这样的东西
unique(setDT(df)[, lapply(.SD, na.omit), by = list(id1, id2)])

答案 1 :(得分:1)

尝试:

library(dplyr) 
df %>%
    group_by(id1, id2) %>%
    summarise_each(funs(mean=mean(., na.rm=TRUE)))

#    id1 id2 v1 v2 v3
# 1   A   X  1  3  4
# 2   B   Y  1  3  4
# 3   C   X  1  3  4
# 4   D   X  1  3  4
# 5   E   Y  1  3  4

或者

df %>% 
    group_by(id1, id2) %>%
    mutate_each(funs(replace(., is.na(.), stats::na.omit(.)))) %>%
    unique()

数据

df <- structure(list(id1 = c("A", "B", "C", "D", "E", "A"), id2 = c("X", 
"Y", "X", "X", "Y", "X"), v1 = c(1L, 1L, 1L, 1L, 1L, NA), v2 = c(NA, 
3L, 3L, 3L, 3L, 3L), v3 = c(NA, 4L, 4L, 4L, 4L, 4L)), .Names = c("id1", 
"id2", "v1", "v2", "v3"), class = "data.frame", row.names = c(NA, 
-6L))

答案 2 :(得分:0)

如果ddf是您的数据框:

> t(sapply(split(ddf, paste(ddf$id1, ddf$id2)), 
           function(x) sapply(x[3:ncol(ddf)], sum, na.rm=T)))
    v1 v2 v3 v4
A X  1  3  4  1
B Y  1  3  4  1
C X  1  3  4  1
D X  1  3  4  1
E Y  1  3  4  1