如何编写 R 函数用 "X" 替换 TRUE 并用 "Y" 替换 FALSE
How to write an R function replace a TRUE with "X" and a FALSE with "Y"
我目前正在尝试编写一个函数来评估字符变量在具有多个数字的字符中是否具有“F”或“M”(即 3849F 是 ID 3849,女性)。我已经整理出一个函数来给我一个布尔值输出,如果 F 存在则为真,如果 M 存在则为假。
我现在如何使用此布尔输出将它们替换为所需的“F”和“M”字符值?
到目前为止我的代码如下:
sex = list()
for (i in 1:length(dataset)){
fsex = grepl("F", dataset, fixed = T)
if (fsex == T) sex = c(sex, "F")
else if (fsex == F) sex = c(sex, "M")
}
这适用于任意布尔向量。您可以改用数据框列。
> bools <- c(T,T,F)
> new_col <- ifelse(bools, "F", "M")
> new_col
[1] "F" "F" "M"
您也可以重新分配原始数据。
> gender <- c(T,T,F)
> gender <- ifelse(gender, "F", "M")
> gender
[1] "F" "F" "M"
如果您使用 dplyr
,您可以通过一个函数实现此目的,而不是需要您已经创建的函数,然后再使用您在问题中提到的第二个函数。
df<- data.frame(
stringsAsFactors = FALSE,
ID = c("125F", "13000M", "13120M", "12260M", "21525F")
)
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
df %>%
mutate(fsex = case_when(
grepl("F", ID) ~ "F",
grepl("M", ID) ~ "M"
))
#> ID fsex
#> 1 125F F
#> 2 13000M M
#> 3 13120M M
#> 4 12260M M
#> 5 21525F F
由 reprex package (v1.0.0)
于 2021 年 3 月 11 日创建
因为您的数据已经包含您希望获得的 F
或 M
值,并且它总是在每个条目的末尾,您可以考虑使用 regex 模式来提取每个条目的最后一个字符,而不是转换为逻辑(即您的函数)然后返回字符(即您要求的函数)。 stringr
包对此很有帮助。
这是一个使用 tidyverse 的例子:
library(dplyr)
library(stringr)
dataset <- data.frame(matrix(paste0(sample(1:100), sample(c("M", "F"))), nrow = 10))
dataset
#> X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
#> 1 74M 59M 69M 96M 66M 53M 4M 43M 30M 33M
#> 2 64F 25F 95F 71F 16F 14F 22F 70F 20F 48F
#> 3 29M 78M 26M 94M 1M 21M 62M 77M 56M 13M
#> 4 61F 49F 86F 50F 51F 82F 91F 52F 7F 32F
#> 5 73M 92M 55M 80M 11M 9M 45M 81M 35M 2M
#> 6 42F 23F 3F 79F 47F 10F 28F 57F 40F 31F
#> 7 65M 63M 88M 38M 27M 76M 67M 75M 83M 15M
#> 8 46F 44F 34F 60F 58F 6F 85F 89F 54F 98F
#> 9 37M 90M 68M 5M 93M 41M 72M 87M 8M 19M
#> 10 99F 18F 17F 97F 24F 12F 39F 100F 84F 36F
dataset %>%
mutate(across(X1:X10, ~ str_extract(., ".$")))
#> X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
#> 1 M M M M M M M M M M
#> 2 F F F F F F F F F F
#> 3 M M M M M M M M M M
#> 4 F F F F F F F F F F
#> 5 M M M M M M M M M M
#> 6 F F F F F F F F F F
#> 7 M M M M M M M M M M
#> 8 F F F F F F F F F F
#> 9 M M M M M M M M M M
#> 10 F F F F F F F F F F
由 reprex package (v1.0.0)
于 2021 年 3 月 10 日创建
@Henrik 提供了我认为是您在评论中寻找的答案,但根据您使用 R 的经验,它可能不清楚。
详细说明:
sex <- c("125F", "X28345M", "2M3")
sex
#>[1] "125F" "X28345M" "2M3"
output <- ifelse(grepl(sex, pattern = "F", ignore.case = TRUE), "F", "M")
output
#>[1] "F" "M" "M"
fsex <- grepl(sex, pattern = "F", ignore.case = TRUE)
#>[1] TRUE FALSE FALSE
您也可以使用这种方法轻松地将“F”和“M”替换为“女”或“男”,或者“0”和“1”。
我目前正在尝试编写一个函数来评估字符变量在具有多个数字的字符中是否具有“F”或“M”(即 3849F 是 ID 3849,女性)。我已经整理出一个函数来给我一个布尔值输出,如果 F 存在则为真,如果 M 存在则为假。
我现在如何使用此布尔输出将它们替换为所需的“F”和“M”字符值?
到目前为止我的代码如下:
sex = list()
for (i in 1:length(dataset)){
fsex = grepl("F", dataset, fixed = T)
if (fsex == T) sex = c(sex, "F")
else if (fsex == F) sex = c(sex, "M")
}
这适用于任意布尔向量。您可以改用数据框列。
> bools <- c(T,T,F)
> new_col <- ifelse(bools, "F", "M")
> new_col
[1] "F" "F" "M"
您也可以重新分配原始数据。
> gender <- c(T,T,F)
> gender <- ifelse(gender, "F", "M")
> gender
[1] "F" "F" "M"
如果您使用 dplyr
,您可以通过一个函数实现此目的,而不是需要您已经创建的函数,然后再使用您在问题中提到的第二个函数。
df<- data.frame(
stringsAsFactors = FALSE,
ID = c("125F", "13000M", "13120M", "12260M", "21525F")
)
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
df %>%
mutate(fsex = case_when(
grepl("F", ID) ~ "F",
grepl("M", ID) ~ "M"
))
#> ID fsex
#> 1 125F F
#> 2 13000M M
#> 3 13120M M
#> 4 12260M M
#> 5 21525F F
由 reprex package (v1.0.0)
于 2021 年 3 月 11 日创建因为您的数据已经包含您希望获得的 F
或 M
值,并且它总是在每个条目的末尾,您可以考虑使用 regex 模式来提取每个条目的最后一个字符,而不是转换为逻辑(即您的函数)然后返回字符(即您要求的函数)。 stringr
包对此很有帮助。
这是一个使用 tidyverse 的例子:
library(dplyr)
library(stringr)
dataset <- data.frame(matrix(paste0(sample(1:100), sample(c("M", "F"))), nrow = 10))
dataset
#> X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
#> 1 74M 59M 69M 96M 66M 53M 4M 43M 30M 33M
#> 2 64F 25F 95F 71F 16F 14F 22F 70F 20F 48F
#> 3 29M 78M 26M 94M 1M 21M 62M 77M 56M 13M
#> 4 61F 49F 86F 50F 51F 82F 91F 52F 7F 32F
#> 5 73M 92M 55M 80M 11M 9M 45M 81M 35M 2M
#> 6 42F 23F 3F 79F 47F 10F 28F 57F 40F 31F
#> 7 65M 63M 88M 38M 27M 76M 67M 75M 83M 15M
#> 8 46F 44F 34F 60F 58F 6F 85F 89F 54F 98F
#> 9 37M 90M 68M 5M 93M 41M 72M 87M 8M 19M
#> 10 99F 18F 17F 97F 24F 12F 39F 100F 84F 36F
dataset %>%
mutate(across(X1:X10, ~ str_extract(., ".$")))
#> X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
#> 1 M M M M M M M M M M
#> 2 F F F F F F F F F F
#> 3 M M M M M M M M M M
#> 4 F F F F F F F F F F
#> 5 M M M M M M M M M M
#> 6 F F F F F F F F F F
#> 7 M M M M M M M M M M
#> 8 F F F F F F F F F F
#> 9 M M M M M M M M M M
#> 10 F F F F F F F F F F
由 reprex package (v1.0.0)
于 2021 年 3 月 10 日创建@Henrik 提供了我认为是您在评论中寻找的答案,但根据您使用 R 的经验,它可能不清楚。
详细说明:
sex <- c("125F", "X28345M", "2M3")
sex
#>[1] "125F" "X28345M" "2M3"
output <- ifelse(grepl(sex, pattern = "F", ignore.case = TRUE), "F", "M")
output
#>[1] "F" "M" "M"
fsex <- grepl(sex, pattern = "F", ignore.case = TRUE)
#>[1] TRUE FALSE FALSE
您也可以使用这种方法轻松地将“F”和“M”替换为“女”或“男”,或者“0”和“1”。