在R中,针对每个组,将同一列中的NA替换为另一行的值

11
我需要用不同行的非NA值替换每行的NA值,仅针对每个组中给定列的数据。
假设有以下示例数据:
id   name
 1     a
 1     NA
 2     b
 3     NA
 3     c
 3     NA

期望输出:

id   name
 1     a
 1     a
 2     b
 3     c
 3     c
 3     c

有没有在R中执行这个操作的方法?


1
如果每个id都至少有一个非 NA 值,那么你可以使用任何向前填充函数来进行最后观测值推导,例如 zoo 包中的函数:zoo::na.locf(df1[with(df1, order(id, name)), ])。此处使用了 @akruns 的数据。 - rawr
3个回答

11

这里有一个使用dplyr的方法。从数据框x中,我们按id分组,并将NA替换为相关值。我假设每个id 只有一个唯一的name值。

x <- data.frame(id = c(1, 1, 2, rep(3,3)), 
 name = c("a", NA, "b", NA, "c", NA), stringsAsFactors=F)

require(dplyr)
x %>%
  group_by(id) %>%
  mutate(name = unique(name[!is.na(name)]))

Source: local data frame [6 x 2]
Groups: id

#  id name
#1  1    a
#2  1    a
#3  2    b
#4  3    c
#5  3    c
#6  3    c

8
我们可以使用 data.table 来完成这个任务。将 'data.frame' 转换为 'data.table' (setDT(df1))。以'id'为分组依据,用'name'中非NA的值替换'name'。
library(data.table)#v1.9.5+
setDT(df1)[, name:= name[!is.na(name)][1L] , by = id]
df1
#   id name
#1:  1    a
#2:  1    a
#3:  2    b
#4:  3    c
#5:  3    c
#6:  3    c

注意:此处假设每个“id”组中只有一个唯一的非缺失值。

另一种选择是将数据集与数据的unique行连接,这些行在我们按'id'和'name' order之后。

 setDT(df1)
 df1[unique(df1[order(id, name)], by='id'), on='id', name:= i.name][]
 #   id name
 #1:  1    a
 #2:  1    a
 #3:  2    b
 #4:  3    c
 #5:  3    c
 #6:  3    c

注意:使用on关键字仅在data.table的开发版本中可用。 安装开发版本的说明请单击此处

数据

df1 <- structure(list(id = c(1L, 1L, 2L, 3L, 3L, 3L), name = c("a", 
NA, "b", NA, "c", NA)), .Names = c("id", "name"),
class = "data.frame",    row.names = c(NA, -6L))

3

基础R

d<-na.omit(df)
transform(df,name=d$name[match(id,d$id)])

再次假设每个ID只有一个唯一的名称(强制执行)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接