如何在 R 中用 map_dl 替换 for 循环

How to replace a for loop with map_dl in R

我想修改 table(具有 2 列和多行的数据框)中的列的值,为第二列的每一行应用一个条件,如果验证通过,则复制的值该单元格并将其粘贴到第一列的同一行。

所以我写了一个代码,它使用 for 循环来完成 table 的每一行 (i)。

代码运行良好,但我想学习如何使用 tidyverse 做同样的事情,特别是使用 map_dl 函数。我到处搜索,但没能正确理解如何使用 map_df 函数。

这是带有 for 循环的代码:

library(tidyverse)

df <- tibble (Color  = "A",
                  Names = c("Jane Yellow", "Max", "Jeff", "Andy", "Lux Yellow", "Elizabeth", "Susan", "David Yellow", "Thomas", "Lisa"))

col_color <- function(df) { 
  
  for(i in 1:nrow(df)){
    if(grepl("Yellow", df[i,2], fixed=TRUE) == TRUE)
    {df[i,1]<- str_extract(df[i,2], "^(?!.*\bYellow\b).*$")}}
  
  for(i in 2:nrow(df)){
    if(df[i,1] == "A") 
    {df[i,1] <- df[i-1,1]}}
  return(df)
}
df <- col_color(df)

我试着用 map_dl 和下面的代码来做,但它不起作用:

library(tidyverse)

df <- tibble (Color  = "A",
                  Names = c("Jane Yellow", "Max", "Jeff", "Andy", "Lux Yellow", "Elizabeth", "Susan", "David Yellow", "Thomas", "Lisa"))

modify_first_column <- function(i) {
  
  if(grepl("Yellow", df[i,2], fixed=TRUE) == TRUE)
  {df[i,1]<- str_extract(df[i,2], "^(?!.*\bYellow\b).*$")}
  
  if(df[i,1] == "A") 
  {df[i,1] <- df[i-1,1]}
  return(df)
}

modify_first_column <- as.tibble(modify_first_column)
df <- map_df(i = 1:nrow(df), modify_first_column)

谁能帮我解决一下?谢谢

您的问题的可能解决方案,但没有循环或映射。但是在tidyverse.

范围内
library(tidyverse)

您的数据:

# A tibble: 10 x 2
   color names       
   <chr> <chr>       
 1 A     Jane Yellow 
 2 A     Max         
 3 A     Jeff        
 4 A     Andy        
 5 A     Lux Yellow  
 6 A     Elizabeth   
 7 A     Susan       
 8 A     David Yellow
 9 A     Thomas      
10 A     Lisa    

第一个条件:

df <- df %>%
  mutate(color = case_when(str_detect(names, "Yellow") ~ names,
                           TRUE ~ color))
# A tibble: 10 x 2
   color        names       
   <chr>        <chr>       
 1 Jane Yellow  Jane Yellow 
 2 A            Max         
 3 A            Jeff        
 4 A            Andy        
 5 Lux Yellow   Lux Yellow  
 6 A            Elizabeth   
 7 A            Susan       
 8 David Yellow David Yellow
 9 A            Thomas      
10 A            Lisa   

第二个条件:

df %>%
  mutate(color = replace(color, color == "A", NA)) %>%
  fill(color)

# A tibble: 10 x 2
   color        names       
   <chr>        <chr>       
 1 Jane Yellow  Jane Yellow 
 2 Jane Yellow  Max         
 3 Jane Yellow  Jeff        
 4 Jane Yellow  Andy        
 5 Lux Yellow   Lux Yellow  
 6 Lux Yellow   Elizabeth   
 7 Lux Yellow   Susan       
 8 David Yellow David Yellow
 9 David Yellow Thomas      
10 David Yellow Lisa