根据R或python中的条件,将一列列表中的值替换为另一列列表中的值
(对于pythonistas,在我得到一些#hatehard之前,下面的代码是R的格式) 这件事让我沮丧太久了 我有两个数据集根据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),
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