根据与 R 中的正则表达式的部分匹配从 data.table 中删除字符串
Removing strings from data.table based on partial match with regex in R
我希望根据部分匹配删除 data.table 中的字符串:
$$ER
由于这些字符串在整个 table 中是不同的,而且我的 table 相当大,效率和速度是首选。我试过 data.table 的 %like% 但这太低效了。 gsub 应该没问题,但我在引用“$$ER”中的“$$”时遇到问题。
structure(list(Country = c("NL", "NL", "NL", "NL", "DE", "DE",
"DE", "GB", "GB"), Value1 = c("$$ER: Data not found", NA, NA,
NA, "$$ERROR: NOT AVAILABLE", NA, NA, "3", "4"), Value2 = c("$$ER: Data not found",
NA, NA, NA, "$$ERROR: NOT AVAILABLE", NA, NA, "3", "4"), Value3 = c(10,
15, 12, 9, 8, 20, 23, 3, 4)), class = "data.frame", row.names = c(NA,
-9L))
Country Value1 Value2 Value3
1 NL $$ER: Data not found $$ER: Data not found 10
2 NL <NA> <NA> 15
3 NL <NA> <NA> 12
4 NL <NA> <NA> 9
5 DE $$ERROR: NOT AVAILABLE $$ERROR: NOT AVAILABLE 8
6 DE <NA> <NA> 20
7 DE <NA> <NA> 23
8 GB 5 6 3
9 GB 6 8 4
期望的输出:
Country Value1 Value2 Value3
1 NL NA NA 10
2 NL NA NA 15
3 NL NA NA 12
4 NL NA NA 9
5 DE NA NA 8
6 DE NA NA 20
7 DE NA NA 23
8 GB 5 6 3
9 GB 6 8 4
您可以在 sapply
测试中使用 startsWith
$$ER
。
D[2:3][sapply(D[2:3], startsWith, "$$ER")] <- NA
D
# Country Value1 Value2 Value3
#1 NL <NA> <NA> 10
#2 NL <NA> <NA> 15
#3 NL <NA> <NA> 12
#4 NL <NA> <NA> 9
#5 DE <NA> <NA> 8
#6 DE <NA> <NA> 20
#7 DE <NA> <NA> 23
#8 GB 3 3 3
#9 GB 4 4 4
但也许您想使用 as.numeric
:
D[2:3] <- sapply(D[2:3], as.numeric)
D
# Country Value1 Value2 Value3
#1 NL NA NA 10
#2 NL NA NA 15
#3 NL NA NA 12
#4 NL NA NA 9
#5 DE NA NA 8
#6 DE NA NA 20
#7 DE NA NA 23
#8 GB 3 3 3
#9 GB 4 4 4
另一种方法是使用 grepl
:
df[apply(df, 2, function(i) grepl('$$ER', i, fixed = T))] <- NA
这将产生以下结果:
# Country Value1 Value2 Value3
# 1 NL <NA> <NA> 10
# 2 NL <NA> <NA> 15
# 3 NL <NA> <NA> 12
# 4 NL <NA> <NA> 9
# 5 DE <NA> <NA> 8
# 6 DE <NA> <NA> 20
# 7 DE <NA> <NA> 23
# 8 GB 3 3 3
# 9 GB 4 4 4
使用data.table
-
library(data.table)
setDT(df)[, (2:3) := lapply(.SD, function(x)
as.numeric(replace(x, grepl('$$ER', x, fixed = TRUE), NA))), .SDcols = 2:3]
df
# Country Value1 Value2 Value3
#1: NL NA NA 10
#2: NL NA NA 15
#3: NL NA NA 12
#4: NL NA NA 9
#5: DE NA NA 8
#6: DE NA NA 20
#7: DE NA NA 23
#8: GB 3 3 3
#9: GB 4 4 4
我希望根据部分匹配删除 data.table 中的字符串:
$$ER
由于这些字符串在整个 table 中是不同的,而且我的 table 相当大,效率和速度是首选。我试过 data.table 的 %like% 但这太低效了。 gsub 应该没问题,但我在引用“$$ER”中的“$$”时遇到问题。
structure(list(Country = c("NL", "NL", "NL", "NL", "DE", "DE",
"DE", "GB", "GB"), Value1 = c("$$ER: Data not found", NA, NA,
NA, "$$ERROR: NOT AVAILABLE", NA, NA, "3", "4"), Value2 = c("$$ER: Data not found",
NA, NA, NA, "$$ERROR: NOT AVAILABLE", NA, NA, "3", "4"), Value3 = c(10,
15, 12, 9, 8, 20, 23, 3, 4)), class = "data.frame", row.names = c(NA,
-9L))
Country Value1 Value2 Value3
1 NL $$ER: Data not found $$ER: Data not found 10
2 NL <NA> <NA> 15
3 NL <NA> <NA> 12
4 NL <NA> <NA> 9
5 DE $$ERROR: NOT AVAILABLE $$ERROR: NOT AVAILABLE 8
6 DE <NA> <NA> 20
7 DE <NA> <NA> 23
8 GB 5 6 3
9 GB 6 8 4
期望的输出:
Country Value1 Value2 Value3
1 NL NA NA 10
2 NL NA NA 15
3 NL NA NA 12
4 NL NA NA 9
5 DE NA NA 8
6 DE NA NA 20
7 DE NA NA 23
8 GB 5 6 3
9 GB 6 8 4
您可以在 sapply
测试中使用 startsWith
$$ER
。
D[2:3][sapply(D[2:3], startsWith, "$$ER")] <- NA
D
# Country Value1 Value2 Value3
#1 NL <NA> <NA> 10
#2 NL <NA> <NA> 15
#3 NL <NA> <NA> 12
#4 NL <NA> <NA> 9
#5 DE <NA> <NA> 8
#6 DE <NA> <NA> 20
#7 DE <NA> <NA> 23
#8 GB 3 3 3
#9 GB 4 4 4
但也许您想使用 as.numeric
:
D[2:3] <- sapply(D[2:3], as.numeric)
D
# Country Value1 Value2 Value3
#1 NL NA NA 10
#2 NL NA NA 15
#3 NL NA NA 12
#4 NL NA NA 9
#5 DE NA NA 8
#6 DE NA NA 20
#7 DE NA NA 23
#8 GB 3 3 3
#9 GB 4 4 4
另一种方法是使用 grepl
:
df[apply(df, 2, function(i) grepl('$$ER', i, fixed = T))] <- NA
这将产生以下结果:
# Country Value1 Value2 Value3
# 1 NL <NA> <NA> 10
# 2 NL <NA> <NA> 15
# 3 NL <NA> <NA> 12
# 4 NL <NA> <NA> 9
# 5 DE <NA> <NA> 8
# 6 DE <NA> <NA> 20
# 7 DE <NA> <NA> 23
# 8 GB 3 3 3
# 9 GB 4 4 4
使用data.table
-
library(data.table)
setDT(df)[, (2:3) := lapply(.SD, function(x)
as.numeric(replace(x, grepl('$$ER', x, fixed = TRUE), NA))), .SDcols = 2:3]
df
# Country Value1 Value2 Value3
#1: NL NA NA 10
#2: NL NA NA 15
#3: NL NA NA 12
#4: NL NA NA 9
#5: DE NA NA 8
#6: DE NA NA 20
#7: DE NA NA 23
#8: GB 3 3 3
#9: GB 4 4 4