我有一个非常简单的问题。但是,我所能找到的都是非常复杂的答案,它们并不能完全满足我的需求。
最接近的东西,我在这里找到:
Answer by flodel and eddi (data.table)
但是,我想根据其他列中的值另外指定如何处理指定列中的NA。
我有一个data.table,其中的列带有NA,其中fac
是一个因子变量。
df <- fread(
"A B C fac H I J iso year matchcode
0 1 1 NA 0 1 0 NLD 2009 NLD2009
1 0 0 NA 1 0 1 NLD 2014 NLD2014
0 0 0 B 1 0 0 AUS 2011 AUS2011
1 0 1 B 0 1 0 AUS 2007 AUS2007
0 1 0 NA 0 1 1 USA 2007 USA2007
0 0 1 NA 0 0 1 USA 2011 USA2010
0 1 0 NA 0 0 0 USA 2013 USA2013
1 0 1 A 0 1 0 BLG 2007 BLG2007
0 1 0 A 1 0 1 BEL 2009 BEL2009
1 0 1 A 0 1 0 BEL 2012 BEL2012",
header = TRUE
)
我想做的就是根据D
中的值,将值E
和fac
分配给列iso3c
中的NA。因此,当iso3c == NLD
时,fac
中的NA应替换为D
,而当iso3c == USA
中fac
中的NA则应替换为E
,导致以下结果。
df <- fread(
"A B C fac H I J iso year matchcode
0 1 1 D 0 1 0 NLD 2009 NLD2009
1 0 0 D 1 0 1 NLD 2014 NLD2014
0 0 0 B 1 0 0 AUS 2011 AUS2011
1 0 1 B 0 1 0 AUS 2007 AUS2007
0 1 0 E 0 1 1 USA 2007 USA2007
0 0 1 E 0 0 1 USA 2011 USA2010
0 1 0 E 0 0 0 USA 2013 USA2013
1 0 1 A 0 1 0 BLG 2007 BLG2007
0 1 0 A 1 0 1 BEL 2009 BEL2009
1 0 1 A 0 1 0 BEL 2012 BEL2012",
header = TRUE
)
编辑:fac
是一个因子变量这一事实带来了一些问题。有效的方法如下:
df$fac<- as.character(df$fac)
df[, fac:= ifelse(is.na(fac) & iso3c == "NLD", "D",
ifelse(is.na(fac) & iso3c == "USA", "E", wbgroup))][]
df[, fac:= factor(fac, levels = c(levels(fac), c('A', 'B', 'C', 'D', 'E', 'F', 'G')))]
答案 0 :(得分:4)
我们需要在i
中指定逻辑条件并进行分配。由于只有两种情况可以更改该值,因此可以分两步完成
df[is.na(fac) & iso == 'NLD', fac := 'D'
][is.na(fac) & iso == 'USA', fac := 'E'][]
# A B C fac H I J iso year matchcode
# 1: 0 1 1 D 0 1 0 NLD 2009 NLD2009
# 2: 1 0 0 D 1 0 1 NLD 2014 NLD2014
# 3: 0 0 0 B 1 0 0 AUS 2011 AUS2011
# 4: 1 0 1 B 0 1 0 AUS 2007 AUS2007
# 5: 0 1 0 E 0 1 1 USA 2007 USA2007
# 6: 0 0 1 E 0 0 1 USA 2011 USA2010
# 7: 0 1 0 E 0 0 0 USA 2013 USA2013
# 8: 1 0 1 A 0 1 0 BLG 2007 BLG2007
# 9: 0 1 0 A 1 0 1 BEL 2009 BEL2009
#10: 1 0 1 A 0 1 0 BEL 2012 BEL2012
如果要替换的值很多,请对键/值数据集进行联接并进行赋值
df[data.table(fac = NA_character_, iso = c('NLD', 'USA'),
val = c('D', 'E')), fac := val, on = .(fac, iso)]
注意:fac
,iso
列是character
类。如果fac
是factor
类,并且列中不存在'D','E'levels
,则在进行赋值之前创建新的levels
,即
df[, fac := factor(fac, levels = c(levels(fac), c('D', 'E')))]
答案 1 :(得分:1)
将data.table
与两个ifelse
语句一起使用的另一种选择。
library(data.table)
df[, fac := ifelse(is.na(fac) & iso == "NLD", "D",
ifelse(is.na(fac) & iso == "USA", "E", fac))][]
# A B C fac H I J iso year matchcode
# 1: 0 1 1 D 0 1 0 NLD 2009 NLD2009
# 2: 1 0 0 D 1 0 1 NLD 2014 NLD2014
# 3: 0 0 0 B 1 0 0 AUS 2011 AUS2011
# 4: 1 0 1 B 0 1 0 AUS 2007 AUS2007
# 5: 0 1 0 E 0 1 1 USA 2007 USA2007
# 6: 0 0 1 E 0 0 1 USA 2011 USA2010
# 7: 0 1 0 E 0 0 0 USA 2013 USA2013
# 8: 1 0 1 A 0 1 0 BLG 2007 BLG2007
# 9: 0 1 0 A 1 0 1 BEL 2009 BEL2009
# 10: 1 0 1 A 0 1 0 BEL 2012 BEL2012