R 中的预处理数据:使用通配符过滤和替换
Pre-processing data in R: filtering and replacing using wildcards
美好的一天!
我有一个数据集,其中我有像 "Invalid"
、"Invalid(N/A)"
、"Invalid(1.23456)"
这样的值,其中很多在不同的列中,并且它们因文件而异。
目标是制作脚本文件来处理不同的 CSV。
我尝试了 read.csv
和 read_csv
,但遇到数据类型错误或没有错误,但也没有采取任何措施。
所有列都是 col_character
除了一列 - col_double
.
试过这个:
is.na(df) <- startsWith(as.character(df, "Inval")
运气不好
试过这个:
is.na(df) <- startsWith(df, "Inval")
运气不好,关于非字符对象的一些错误
试过这个:
df %>%
mutate(across(everything(), .fns = ~str_replace(., "invalid", NA_character_)))
运气不好
和其他 google 东西 - 再一次运气不好,数据类型错误或没有错误,但也没有采取任何措施。
那么 R 无法在数据框中进行简单的查找和替换,对吗?
data frame exampl
dput(dtype_Result[1:20, 1:4])
的输出
structure(list(Location = c("1(1,A1)", "2(1,B1)", "3(1,C1)",
"4(1,D1)", "5(1,E1)", "6(1,F1)", "7(1,G1)", "8(1,H1)", "9(1,A2)",
"10(1,B2)", "11(1,C2)", "12(1,D2)", "13(1,E2)", "14(1,F2)", "15(1,G2)",
"16(1,H2)", "17(1,A3)", "18(1,B3)", "19(1,C3)", "20(1,D3)"),
Sample = c("Background0", "Background0", "Standard1", "Standard1",
"Standard2", "Standard2", "Standard3", "Standard3", "Standard4",
"Standard4", "Standard5", "Standard5", "Standard6", "Standard6",
"Control1", "Control1", "Control2", "Control2", "Unknown1",
"Unknown1"), EGF = c(NA, NA, "6.71743640129069", "2.66183193679533",
"16.1289784536322", "16.1289784536322", "78.2706654825781",
"78.6376213069722", "382.004087907716", "447.193928257862",
"Invalid(N/A)", "1920.90297258996", "7574.57784103579", "29864.0308009592",
"167.830723655146", "109.746615928611", "868.821939675054",
"971.158518683179", "9.59119569511596", "4.95543581398464"
), `FGF-2` = c(NA, NA, "25.5436745776637", NA, "44.3280630362038",
NA, "91.991708192168", "81.9459159768959", "363.563899234418",
"425.754478700876", "Invalid(2002.97340881547)", "2027.71958119836",
"9159.40221389147", "11138.8722428849", "215.58494072476",
"70.9775438699825", "759.798876479002", "830.582605561901",
"58.7007261370257", "70.9775438699825")), row.names = c(NA,
-20L), class = c("tbl_df", "tbl", "data.frame"))
错误在startsWith
的使用中。以下 grepl
解决方案更简单且有效。
is.na(df) <- sapply(df, function(x) grepl("^Invalid", x))
str_replace
函数将尝试编辑字符串的内容,插入部分替换,而不是完全替换。此外,across
函数针对所有列,包括数字 ID。以下代码有效,基于您提供的 tidyverse 示例。
要修复它,请使用 where
识别感兴趣的列,然后使用 if_else
在存在部分字符串匹配时使用 NA 值覆盖数据,使用 str_detect
找到目标文本。
示例数据
library(tiyverse)
df <- tibble(
id = 1:3,
x = c("a", "invalid", "c"),
y = c("d", "e", "Invalid/NA")
)
df
# A tibble: 3 x 3
id x y
<int> <chr> <chr>
1 1 a d
2 2 invalid e
3 3 c Invalid/NA
解决方案
df <- df %>%
mutate(
across(where(is.character),
.fns = ~if_else(str_detect(tolower(.x), "invalid"), NA_character_, .x))
)
print(df)
结果
# A tibble: 3 x 3
id x y
<int> <chr> <chr>
1 1 a d
2 2 NA e
3 3 c NA
美好的一天!
我有一个数据集,其中我有像 "Invalid"
、"Invalid(N/A)"
、"Invalid(1.23456)"
这样的值,其中很多在不同的列中,并且它们因文件而异。
目标是制作脚本文件来处理不同的 CSV。
我尝试了 read.csv
和 read_csv
,但遇到数据类型错误或没有错误,但也没有采取任何措施。
所有列都是 col_character
除了一列 - col_double
.
试过这个:
is.na(df) <- startsWith(as.character(df, "Inval")
运气不好
试过这个:
is.na(df) <- startsWith(df, "Inval")
运气不好,关于非字符对象的一些错误
试过这个:
df %>%
mutate(across(everything(), .fns = ~str_replace(., "invalid", NA_character_)))
运气不好
和其他 google 东西 - 再一次运气不好,数据类型错误或没有错误,但也没有采取任何措施。
那么 R 无法在数据框中进行简单的查找和替换,对吗?
data frame exampl
dput(dtype_Result[1:20, 1:4])
structure(list(Location = c("1(1,A1)", "2(1,B1)", "3(1,C1)",
"4(1,D1)", "5(1,E1)", "6(1,F1)", "7(1,G1)", "8(1,H1)", "9(1,A2)",
"10(1,B2)", "11(1,C2)", "12(1,D2)", "13(1,E2)", "14(1,F2)", "15(1,G2)",
"16(1,H2)", "17(1,A3)", "18(1,B3)", "19(1,C3)", "20(1,D3)"),
Sample = c("Background0", "Background0", "Standard1", "Standard1",
"Standard2", "Standard2", "Standard3", "Standard3", "Standard4",
"Standard4", "Standard5", "Standard5", "Standard6", "Standard6",
"Control1", "Control1", "Control2", "Control2", "Unknown1",
"Unknown1"), EGF = c(NA, NA, "6.71743640129069", "2.66183193679533",
"16.1289784536322", "16.1289784536322", "78.2706654825781",
"78.6376213069722", "382.004087907716", "447.193928257862",
"Invalid(N/A)", "1920.90297258996", "7574.57784103579", "29864.0308009592",
"167.830723655146", "109.746615928611", "868.821939675054",
"971.158518683179", "9.59119569511596", "4.95543581398464"
), `FGF-2` = c(NA, NA, "25.5436745776637", NA, "44.3280630362038",
NA, "91.991708192168", "81.9459159768959", "363.563899234418",
"425.754478700876", "Invalid(2002.97340881547)", "2027.71958119836",
"9159.40221389147", "11138.8722428849", "215.58494072476",
"70.9775438699825", "759.798876479002", "830.582605561901",
"58.7007261370257", "70.9775438699825")), row.names = c(NA,
-20L), class = c("tbl_df", "tbl", "data.frame"))
错误在startsWith
的使用中。以下 grepl
解决方案更简单且有效。
is.na(df) <- sapply(df, function(x) grepl("^Invalid", x))
str_replace
函数将尝试编辑字符串的内容,插入部分替换,而不是完全替换。此外,across
函数针对所有列,包括数字 ID。以下代码有效,基于您提供的 tidyverse 示例。
要修复它,请使用 where
识别感兴趣的列,然后使用 if_else
在存在部分字符串匹配时使用 NA 值覆盖数据,使用 str_detect
找到目标文本。
示例数据
library(tiyverse)
df <- tibble(
id = 1:3,
x = c("a", "invalid", "c"),
y = c("d", "e", "Invalid/NA")
)
df
# A tibble: 3 x 3
id x y
<int> <chr> <chr>
1 1 a d
2 2 invalid e
3 3 c Invalid/NA
解决方案
df <- df %>%
mutate(
across(where(is.character),
.fns = ~if_else(str_detect(tolower(.x), "invalid"), NA_character_, .x))
)
print(df)
结果
# A tibble: 3 x 3
id x y
<int> <chr> <chr>
1 1 a d
2 2 NA e
3 3 c NA