如何在 R 中为长列表“替换”(或等效函数)
how to `replace` (or equivalent function) in R for long lists
我希望能够在 R 中的 data.frame 对象中替换向量中的元素值的子集。到目前为止,我发现的玩具示例非常简单(而且很小),足以手动进行键入要定位的少数元素并将其替换为要替换的元素。虽然这个玩具示例再次足够小,可以手动键入目标和替换元素,但我希望它可以作为一种简单的表示形式,其中有 更多独特的名称,但问题保持不变:
SampleID <- rep(c("Keith", "Mick", "Brian", "Ronnie"), times = 3)
Trial <- sort(rep(c(1,2,3), times = 4))
set.seed(10)
Scores <- sample.int(100, 12)
df <- data.frame(SampleID, Trial, Scores)
现在以这个例子为例,将其扩展到包含数千个唯一的独立 SampleID 名称;假设这项研究实际上有一个大约 5000 个独特个体的列表,并且您的数据集需要重新编码,以便需要重命名 100 个个体。
有没有一种方法可以利用两个向量来表示要用要重新编码的 replacement
名称替换的已识别 target
名称的列表,而无需键入类似以下内容:
df$SampleID <- recode(df$SampleID, "Mick" = "jagger", ... 99 other "target" = "replacement" values)
也许诀窍是使用 for 循环进行迭代?
非常感谢。
我会创建一个命名向量并将其与 forcats::fct_recode
:
一起使用
library(forcats)
library(dplyr)
names(target) <- replacement
df <- df %>%
mutate(SampleID = fct_recode(SampleID, target))
我建议创建一个包含 target
和 replacement
字段的参考数据框,如下所示:
new_df <- data.frame(target = 'Mick', replacement = 'Jagger')
然后你可以将它合并到你当前的 df
:
df <- merge(df, new_df, by.x = 'SampleID', by.y = 'target', all.x = TRUE)
那么只需使用 ifelse()
语句将 SampleID
中的值替换为 replacement
中的值,其中 !is.na(replacement)
:
df$SampleID <- ifelse(!is.na(df$replacement), df$replacement, df$SampleID)
要明确放入玩具替换向量以使用:
replace_list <- list(target = c('Keith', 'Mick', 'Brian', 'Ronnie'),
replacement = c('Richards', 'Jagger', 'Jones', 'Wood'))
可能有更优雅的解决方案,但如果您只想使用字符串向量,也许可以使用一个简单的查找函数,然后将其映射到目标向量的每个元素上。
replace_funct <- function(x) {
if (!is.na(replace_list$target[[x]]))
replace_list$replacement[[which(replace_list$target == x)]]
else x
}
library(purrr)
df$NewSampleID <- map_chr(df$SampleID, replace_funct)
我希望能够在 R 中的 data.frame 对象中替换向量中的元素值的子集。到目前为止,我发现的玩具示例非常简单(而且很小),足以手动进行键入要定位的少数元素并将其替换为要替换的元素。虽然这个玩具示例再次足够小,可以手动键入目标和替换元素,但我希望它可以作为一种简单的表示形式,其中有 更多独特的名称,但问题保持不变:
SampleID <- rep(c("Keith", "Mick", "Brian", "Ronnie"), times = 3)
Trial <- sort(rep(c(1,2,3), times = 4))
set.seed(10)
Scores <- sample.int(100, 12)
df <- data.frame(SampleID, Trial, Scores)
现在以这个例子为例,将其扩展到包含数千个唯一的独立 SampleID 名称;假设这项研究实际上有一个大约 5000 个独特个体的列表,并且您的数据集需要重新编码,以便需要重命名 100 个个体。
有没有一种方法可以利用两个向量来表示要用要重新编码的 replacement
名称替换的已识别 target
名称的列表,而无需键入类似以下内容:
df$SampleID <- recode(df$SampleID, "Mick" = "jagger", ... 99 other "target" = "replacement" values)
也许诀窍是使用 for 循环进行迭代?
非常感谢。
我会创建一个命名向量并将其与 forcats::fct_recode
:
library(forcats)
library(dplyr)
names(target) <- replacement
df <- df %>%
mutate(SampleID = fct_recode(SampleID, target))
我建议创建一个包含 target
和 replacement
字段的参考数据框,如下所示:
new_df <- data.frame(target = 'Mick', replacement = 'Jagger')
然后你可以将它合并到你当前的 df
:
df <- merge(df, new_df, by.x = 'SampleID', by.y = 'target', all.x = TRUE)
那么只需使用 ifelse()
语句将 SampleID
中的值替换为 replacement
中的值,其中 !is.na(replacement)
:
df$SampleID <- ifelse(!is.na(df$replacement), df$replacement, df$SampleID)
要明确放入玩具替换向量以使用:
replace_list <- list(target = c('Keith', 'Mick', 'Brian', 'Ronnie'),
replacement = c('Richards', 'Jagger', 'Jones', 'Wood'))
可能有更优雅的解决方案,但如果您只想使用字符串向量,也许可以使用一个简单的查找函数,然后将其映射到目标向量的每个元素上。
replace_funct <- function(x) {
if (!is.na(replace_list$target[[x]]))
replace_list$replacement[[which(replace_list$target == x)]]
else x
}
library(purrr)
df$NewSampleID <- map_chr(df$SampleID, replace_funct)