根据R或python中的条件,将一列列表中的值替换为另一列列表中的值

根据R或python中的条件,将一列列表中的值替换为另一列列表中的值,python,r,data-analysis,data-cleaning,Python,R,Data Analysis,Data Cleaning,(对于pythonistas,在我得到一些#hatehard之前,下面的代码是R的格式) 这件事让我沮丧太久了 我有两个数据集 df1 <- data.frame(ID = c("Person.A", "Person.B", "Person.C", "Person.D", "Person.E", "Person.F"), Aa = c(0,1,2,NA,1,1), Ab = c(0,NA,2,1,1,1),

(对于pythonistas,在我得到一些#hatehard之前,下面的代码是R的格式)

这件事让我沮丧太久了

我有两个数据集

df1 <- data.frame(ID = c("Person.A", "Person.B", "Person.C", "Person.D", "Person.E", "Person.F"),
                  Aa = c(0,1,2,NA,1,1),
                  Ab = c(0,NA,2,1,1,1),
                  Ac = c(NA,NA,2,2,1,1),
                  no.match = c(0,1,2,2,1,2))

df2 <- data.frame(ID = c("Person.A", "Person.B", "Person.C", "Person.D", "Person.E"),
                  Ba = c(0,NA,2,1,1),
                  Bb = c(NA,1,2,2,1),
                  Bc = c(0,1,2,2,1))
实际的数据集要复杂得多,因为许多列在其他列中没有匹配项。所以我不认为我能做什么取决于柱子的排列

Aa
Ba
列包含相同的信息;列
Ab
Bb
也可以,依此类推,但列
no.match
不包含匹配列

如果
Aa
为NA,我想将
Ba
同一行的值“映射”到
Aa
,并对
Ab
Bb
Ac
Bc
等执行相同的操作

本例中的结果DF如下所示:

        ID Aa Ab Ac no.match Ba Bb Bc
1 Person.A  0  0  0      0    0 NA  0
2 Person.B  1  1  1      1    NA  1  1
3 Person.C  2  2  2      2    2  2  2
4 Person.D  1  1  2      2    1  2 NA
5 Person.E  1  1  1      1    1  1  1
6 Person.F  1  1  1      2    NA NA NA
其中元素
[4,2]
替换为元素
[4,6]
行和列需要匹配

我尝试了大量令人尴尬的事情:
apply
ifelse
,迭代了一系列列
l1=c('Aa','Ab','Ac'),l2=c('Ba','Bb','Bc')


我可以一次性完成:
它(即.na(mdf$Aa))下面是一个使用
data.table v1.9.5
-安装说明:

require(data.table)#v1.9.5+
cols1=名称(df1)[2:4]
cols2=名称(df2)[2:4]
富df1
#ID Aa Ab Ac编号匹配Ba Bb Bc
#1:人。一个0纳0
#2:个人B 1 NA 1 1
#3:个人。C2
#4:人D 1 2 1 2
#5:人.e1
#6:人。F 1 1 2 NA NA NA
  • setDT()
    通过引用将
    df1
    转换为data.table

  • setDT(df1)[df2,on=“ID”]
    执行连接。对于
    df2
    的每一行,我们在
    df1
    中查找匹配行,并提取匹配行对应的列

  • 在匹配行上,我们使用
    :=
    操作符通过引用更新
    cols1
    中的列,并在
    cols2
    中添加新列。对于更新列,我们提取
    cols1
    cols2
    中指定的列,并用函数
    foo()
    替换
    NA
    s。对于添加列,我们只需使用
    mget()
    拉取列
    cols2
    。我们使用
    c()
    连接这两个列表


如果您感兴趣,请看一看,了解更多信息。

我想我可能是因为自己太笨了。我不知道这是让我高兴还是悲伤,但我想我有事情要做。如果有人有一个更优雅的解决方案,我仍然会感兴趣。再次感谢!我想把问题写出来对我有帮助<代码>mdf[,c(“Aa”,“Ab”,“Ac”)][is.na(mdf[,c(“Aa”,“Ab”,“Ac”)])]感谢您的回答,更感谢您的解释。我可以问一下如何更改函数以将cols2的行和插入cols1的Nas中吗?再次感谢!
        ID Aa Ab Ac no.match Ba Bb Bc
1 Person.A  0  0  0      0    0 NA  0
2 Person.B  1  1  1      1    NA  1  1
3 Person.C  2  2  2      2    2  2  2
4 Person.D  1  1  2      2    1  2 NA
5 Person.E  1  1  1      1    1  1  1
6 Person.F  1  1  1      2    NA NA NA
require(data.table) # v1.9.5+
cols1 = names(df1)[2:4]
cols2 = names(df2)[2:4]

foo <- function(x, y) {
    nas = is.na(x)
    x[nas] = y[nas]
    x
}
setDT(df1)[df2, c(cols1, cols2) := c(Map(foo, mget(cols1), 
                   mget(cols2)), mget(cols2)), on = "ID"]

> df1
#          ID Aa Ab Ac no.match Ba Bb Bc
# 1: Person.A  0  0  0        0  0 NA  0
# 2: Person.B  1  1  1        1 NA  1  1
# 3: Person.C  2  2  2        2  2  2  2
# 4: Person.D  1  1  2        2  1  2  2
# 5: Person.E  1  1  1        1  1  1  1
# 6: Person.F  1  1  1        2 NA NA NA