在 dplyr 链中调用 mutate 的 gsub 内部函数给出错误
gsub inside function with mutate called in dplyr chain gives error
我有以下示例数据(真实数据包含具有数字和字符变量的其他列):
structure(list(AM = structure(1:20, .Label = c("AMP_R", "AZI_R",
"CHL_R", "CIP_R", "COL_R", "ERY_R", "ETP_R", "F.C_R", "FEP_R",
"FOT_R", "FOX_R", "GEN_R", "IMI_R", "MERO_R", "NAL_R", "STR_R",
"SULFA_R", "T.C_R", "TAZ_R", "TET_R"), class = "factor")), .Names = "AM", row.names = c(NA,
-20L), class = "data.frame")
我试图创建一个函数来检测数据框中的列是否包含以“_R”结尾的变量。如果他们这样做,它将删除这个结尾并根据转换 table 继续将变量重命名为全名。如果“_R”结尾不存在,它将直接转换名称。
我在函数的第一部分尝试了以下操作:
library(dplyr)
convert_AM_names <- function(data, col) {
data %>%
mutate(col = gsub("(.*?)_R", "\1", col))
}
我想在 dplyr 链中使用它,像这样:
AM <- AM %>%
rowwise() %>%
convert_AM_names(., AM)
但是,当我这样做时,出现错误 "Error in mutate_impl(.data, dots): Column "col" must be length 1, not 20"
我看到类似的问题已在 SO 此处得到解决,但对于大多数问题,解决方案是使用 rowwise(),这在此处似乎不起作用。有什么建议吗?
您可以使用 mutate_at()
,它允许您 select 列并对其应用函数。
AM %>%
mutate_at(.vars = "AM",
.funs = gsub,
pattern = "(.*?)_R",
replacement = "\1")
如果你愿意,你也可以重写你的函数:
convert_AM_names <- function(col) {
gsub("(.*?)_R", "\1", col)
}
并在mutate_at()
中使用:
AM %>%
mutate_at(.vars = "AM",
.funs = convert_AM_names)
在这两种情况下,结果如下所示:
AM
1 AMP
2 AZI
3 CHL
4 CIP
5 COL
6 ERY
7 ETP
8 F.C
9 FEP
10 FOT
11 FOX
12 GEN
13 IMI
14 MERO
15 NAL
16 STR
17 SULFA
18 T.C
19 TAZ
20 TET
您可以为正则表达式使用 锚点,它仅在 _R
正好位于末尾时才匹配:
convert_AM_names <- function(col) {
gsub("(.*)_R$", "\1", col)
}
library(dplyr)
df %>%
mutate(AM = convert_AM_names(AM))
或直接 - 没有 convert_AM_names()
的开销:
df %>%
mutate(AM = gsub("(.*)_R$", "\1", AM))
两者都会产生:
AM
1 AMP
2 AZI
3 CHL
4 CIP
5 COL
6 ERY
7 ETP
8 F.C
9 FEP
10 FOT
11 FOX
12 GEN
13 IMI
14 MERO
15 NAL
16 STR
17 SULFA
18 T.C
19 TAZ
20 TET
我有以下示例数据(真实数据包含具有数字和字符变量的其他列):
structure(list(AM = structure(1:20, .Label = c("AMP_R", "AZI_R",
"CHL_R", "CIP_R", "COL_R", "ERY_R", "ETP_R", "F.C_R", "FEP_R",
"FOT_R", "FOX_R", "GEN_R", "IMI_R", "MERO_R", "NAL_R", "STR_R",
"SULFA_R", "T.C_R", "TAZ_R", "TET_R"), class = "factor")), .Names = "AM", row.names = c(NA,
-20L), class = "data.frame")
我试图创建一个函数来检测数据框中的列是否包含以“_R”结尾的变量。如果他们这样做,它将删除这个结尾并根据转换 table 继续将变量重命名为全名。如果“_R”结尾不存在,它将直接转换名称。
我在函数的第一部分尝试了以下操作:
library(dplyr)
convert_AM_names <- function(data, col) {
data %>%
mutate(col = gsub("(.*?)_R", "\1", col))
}
我想在 dplyr 链中使用它,像这样:
AM <- AM %>%
rowwise() %>%
convert_AM_names(., AM)
但是,当我这样做时,出现错误 "Error in mutate_impl(.data, dots): Column "col" must be length 1, not 20"
我看到类似的问题已在 SO 此处得到解决,但对于大多数问题,解决方案是使用 rowwise(),这在此处似乎不起作用。有什么建议吗?
您可以使用 mutate_at()
,它允许您 select 列并对其应用函数。
AM %>%
mutate_at(.vars = "AM",
.funs = gsub,
pattern = "(.*?)_R",
replacement = "\1")
如果你愿意,你也可以重写你的函数:
convert_AM_names <- function(col) {
gsub("(.*?)_R", "\1", col)
}
并在mutate_at()
中使用:
AM %>%
mutate_at(.vars = "AM",
.funs = convert_AM_names)
在这两种情况下,结果如下所示:
AM
1 AMP
2 AZI
3 CHL
4 CIP
5 COL
6 ERY
7 ETP
8 F.C
9 FEP
10 FOT
11 FOX
12 GEN
13 IMI
14 MERO
15 NAL
16 STR
17 SULFA
18 T.C
19 TAZ
20 TET
您可以为正则表达式使用 锚点,它仅在 _R
正好位于末尾时才匹配:
convert_AM_names <- function(col) {
gsub("(.*)_R$", "\1", col)
}
library(dplyr)
df %>%
mutate(AM = convert_AM_names(AM))
或直接 - 没有 convert_AM_names()
的开销:
df %>%
mutate(AM = gsub("(.*)_R$", "\1", AM))
两者都会产生:
AM
1 AMP
2 AZI
3 CHL
4 CIP
5 COL
6 ERY
7 ETP
8 F.C
9 FEP
10 FOT
11 FOX
12 GEN
13 IMI
14 MERO
15 NAL
16 STR
17 SULFA
18 T.C
19 TAZ
20 TET