如何在 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
我想修改 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