【问题标题】:How to replace NAs of a variable with values from another dataframe如何用另一个数据帧中的值替换变量的 NA
【发布时间】:2015-04-25 04:06:24
【问题描述】:

我希望这个不是愚蠢的。

我有两个带有变量 ID 和性别/性别的数据框。在 df1 中,有 NA。在df2中,变量是完整的。我想用 df2 中的值完成 df1 中的列。 (在 df1 中,该变量称为“性别”。在 df2 中,该变量称为“性别”。)

这是我目前尝试过的:

#example-data
ID<-seq(1,30,by=1)
df1<-as.data.frame(ID)
df2<-df1
df1$gender<-c(NA,"2","1",NA,"2","2","2","2","2","2",NA,"2","1","1",NA,"2","2","2","2","2","1","2","2",NA,"2","2","2","2","2",NA)
df2$sex<-c("2","2","1","2","2","2","2","2","2","2","2","2","1","1","2","2","2","2","2","2","1","2","2","2","2","2","2","2","2","2")


#Approach 1: 
NAs.a <- is.na(df1$gender)
df1$gender[NAs.a] <- df2[match(df1$ID[NAs.a], df2$ID),]$sex

#Approach 2 (i like dplyr a lot, perhaps there´s a way to use it):
library("dplyr")
temp<-df2 %>% select(ID,gender)

#EDIT:
#df<-left_join(df1$gender,df2$gender, by="ID") 
 df<-left_join(df1,df2, by="ID") 

非常感谢。

【问题讨论】:

  • 好的,我遇到了这个问题:table(Datensatz$gender, useNA="always") 带来 0/1/NA 然后table(sampleframe$sex) 有 0/1。那么&gt; Datensatz$gender[NAs.a] &lt;- sampleframe[match(Datensatz$ID[NAs.a], sampleframe$ID),]$sex &gt; table(Datensatz$gender, useNA="always") 怎么给我带来了 4 倍的值“2”? 0 1 2 279 294 4 0
  • 其实你用match的第一个方法应该很有效,为什么不喜欢呢?
  • 我喜欢它,但是对于我的数据(不是示例数据),我没有得到 0 和 1 的值,还有 2(4 次)。我不知道哪里出了问题,因为两列都只包含 0 和 1。
  • 您是否尝试过df1[df2, sex := i.sex][is.na(gender), gender := sex][],就像我在 cmets 中建议的那样?这将向您显示两列,以便您可以比较并查看所有内容是否正确匹配。它还将通过引用修改df1
  • 是的,但我收到此错误::=(sex, i.sex) 中的错误:检查 is.data.table(DT) == TRUE。否则,:= 和:=(...) 被定义为在 j 中使用,仅一次且以特定方式使用。请参阅帮助(“:=”)。

标签: r match dplyr na


【解决方案1】:

这是使用data.tables 二进制连接的快速解决方案,这将gendersex 连接起来,其余所有列保持不变

library(data.table)
setkey(setDT(df1), ID)
df1[df2, gender := i.sex][]
#     ID gender
#  1:  1      2
#  2:  2      2
#  3:  3      1
#  4:  4      2
#  5:  5      2
#  6:  6      2
#  7:  7      2
#  8:  8      2
#  9:  9      2
# 10: 10      2
# 11: 11      2
# 12: 12      2
# 13: 13      1
# 14: 14      1
# 15: 15      2
# 16: 16      2
# 17: 17      2
# 18: 18      2
# 19: 19      2
# 20: 20      2
# 21: 21      1
# 22: 22      2
# 23: 23      2
# 24: 24      2
# 25: 25      2
# 26: 26      2
# 27: 27      2
# 28: 28      2
# 29: 29      2
# 30: 30      2

【讨论】:

  • 这只是替换 NA,还是替换整个列?
  • 如果你只想替换NAs的性别,你可以做类似df1[df2, sex := i.sex][is.na(gender), gender := sex][]的事情。尽管dplyr 的答案也加入了整个专栏,但您似乎对此没有意见
【解决方案2】:

这可能是使用基础 R 最简单的方法。

idx <- is.na(df1$gender)
df1$gender[idx] = df2$sex[idx]

【讨论】:

  • 谢谢,但是当两个向量的长度不同时,这似乎不起作用。
【解决方案3】:

你可以的

df1 %>% select(ID) %>% left_join(df2, by = "ID")
#   ID sex
#1   1   2
#2   2   2
#3   3   1
#4   4   2
#5   5   2
#6   6   2
#.. ..  

这假设 - 如示例中一样 - 来自 df1 的所有 ID 也存在于 df2 中,并且在那里具有性别/性别信息。


如果您的数据中有其他列,您也可以尝试这样做:

df1 %>% select(-gender) %>% left_join(df2[c("ID", "sex")], by = "ID")

【讨论】:

  • @user2982730,您是否使用了示例中的数据?我没有收到 dplyr 0.4.1 的任何错误
猜你喜欢
  • 1970-01-01
  • 2019-02-05
  • 2013-08-06
  • 1970-01-01
  • 2021-10-03
  • 2016-07-24
  • 2019-08-06
  • 2021-01-07
  • 1970-01-01
相关资源
最近更新 更多