根据另一列中的值用预定值替换列中的 NA
Replacing NA's in a column with predetermined values based on the value in another column
我有一个非常简单的问题。然而,我所能找到的都是非常复杂的答案,不能完全满足我的需要。
最接近的,我在这里找到:
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
)
我想做的是根据 iso3c
中的值将值 D
和 E
分配给列 fac
中的 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')))]
我们需要在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
如果要替换的值很多,则与 key/value 数据集进行连接并进行赋值
df[data.table(fac = NA_character_, iso = c('NLD', 'USA'),
val = c('D', 'E')), fac := val, on = .(fac, iso)]
注意:fac
、iso
列是 character
class。如果 fac
是 factor
class,并且 'D'、'E' levels
不存在于列中,则创建新的 levels
在做作业之前,即
df[, fac := factor(fac, levels = c(levels(fac), c('D', 'E')))]
另一个使用 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
我有一个非常简单的问题。然而,我所能找到的都是非常复杂的答案,不能完全满足我的需要。
最接近的,我在这里找到:
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
)
我想做的是根据 iso3c
中的值将值 D
和 E
分配给列 fac
中的 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')))]
我们需要在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
如果要替换的值很多,则与 key/value 数据集进行连接并进行赋值
df[data.table(fac = NA_character_, iso = c('NLD', 'USA'),
val = c('D', 'E')), fac := val, on = .(fac, iso)]
注意:fac
、iso
列是 character
class。如果 fac
是 factor
class,并且 'D'、'E' levels
不存在于列中,则创建新的 levels
在做作业之前,即
df[, fac := factor(fac, levels = c(levels(fac), c('D', 'E')))]
另一个使用 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