在函数中组合 for 循环和 mutate 的 case_match

问题描述 投票:0回答:1

我正在尝试使用

mutate
包中的
case_match
dplyr
创建一个函数,作为我的分析工作的一部分。但是,为了完全自动化该过程,我想包含一个额外的数据框(作为函数中的参数),其中包含文本字符串对,如果在包含数据的数据框中找到这些文本字符串对,这些文本字符串对将被更改。

没有 for 循环,这可以完美地工作:

dftest <- data.frame(old = c("ones","twos","fours","fives"), new = c("Humanoid",
"Hairy","Hairy","what"))
test1 <- data.frame(spp= c("ones", "twos", "threes"), log = c(5,61,36))

updnames <- function(df, col, names_df) {
    require(dplyr)
    if(ncol(names_df)>2)
    {stop("More than 2 columns in names dataframe")}
    if(sum(duplicated(names_df[1]))>0)
    {stop("Duplicate old species names")}
    else
    {
        names_df <- names_df %>% mutate_all(as.character)
        df <- df %>%
                mutate(updnames = case_match({{col}},
                    names_df[1,1] ~ names_df[1,2],
                    names_df[2,1] ~ names_df[2,2],
                    names_df[3,1] ~ names_df[3,2],
                    names_df[4,1] ~ names_df[4,2],
                    .default = {{col}}))}
    return(df)
}

test2 <- updnames(test1, spp,dftest)


> test2 # Correct output
     spp log updnames
1   ones   5 Humanoid
2   twos  61    Hairy
3 threes  36   threes

添加 for 循环不起作用。新列已按预期创建,但列值只是重复:

updnames <- function(df, col, names_df) {
  require(dplyr)
  if(ncol(names_df)>2)
  {stop("More than 2 columns in names dataframe")}
  if(sum(duplicated(names_df[1]))>0)
  {stop("Duplicate old species names")}
  else
  {
  names_df <- names_df %>% mutate_all(as.character)
  for(i in 1:nrow(names_df)){
    df <- df %>%
  mutate(updnames = case_match({{col}},
      names_df[i,1] ~ names_df[i,2],
      .default = {{col}}))}
  }
  return(df)
}

test2 <- updnames(test1, spp, dftest)

> test2 # Wrong output
     spp log updnames
1   ones   5     ones
2   twos  61     twos
3 threes  36   threes

我尝试查看 Stack Overflow 上的各种其他帖子并阅读相关文档,但我似乎无法弄清楚。

如果有人对我想要实现的目标有任何想法或替代解决方案,我将不胜感激。

r for-loop dplyr mutate
1个回答
0
投票

使用

recode

test1 %>% 
  mutate(new_spp = recode(spp, !!!deframe(dftest)))

     spp log  new_spp
1   ones   5 Humanoid
2   twos  61    Hairy
3 threes  36   threes

以函数格式执行:

update_names <- function(df, col, new_names){
     df %>% mutate(updnames = recode({{col}},!!!deframe(new_names)))
 }
 update_names(test1,spp, dftest)
     spp log updnames
1   ones   5 Humanoid
2   twos  61    Hairy
3 threes  36   threes
© www.soinside.com 2019 - 2024. All rights reserved.