繁体   English   中英

如何在数据框列表中使用purrr :: map来修改特定数据框中的列值,而不更改列表中的其他数据框?

[英]How do I use purrr::map with dataframe list to modify column values in specific dataframes without changing other dataframes in list?

  • 我有一个名为df_list的许多数据帧的列表( survey08survey09survey10等)。

  • 每个数据框包含2列,分别命名为yearemployed

# create 3 dataframes with identical column names
survey08 <- data.frame(year = 2008, employed = c(1, 2, 2, 1, 2))
survey09 <- data.frame(year = 2009, employed = c(1, 1, 1, 2, 1))
survey10 <- data.frame(year = 2010, employed = c(2, 1, 1, 1, 1))

# put dataframes into a list
df_list <- list(survey08, survey09, survey10)

# add names for dataframes in list
# names correspond to survey year ('year' column)
names(df_list) <- c("survey08", "survey09", "survey10")

我想重新编码所employed列中的值(1 =是,2 =否),但仅在survey08survey09数据框中。 对于列表中的其他数据框,我想保留原始列值(即,仅修改列表中的特定DF)。

我使用year列作为过滤器尝试了以下代码:

library(tidyverse)

# modify only values in 'employed' column for DFs 'survey08' and 'survey09' 
# use 'year' column as filter

df_list %>% 
  map(~filter(.x, year %in% 2008:2009)) %>% 
  map(~ .x %>% mutate_at(vars(employed), ~recode_factor(.,`1` = "yes", `2` = "no")))

虽然这可以正确地重新编码两个数据帧( survey08survey09 ),但它不会保留列表中其他数据帧的值。

电流输出:

#> $survey08
#>   year employed
#> 1 2008      yes
#> 2 2008       no
#> 3 2008       no
#> 4 2008      yes
#> 5 2008       no
#> 
#> $survey09
#>   year employed
#> 1 2009      yes
#> 2 2009      yes
#> 3 2009      yes
#> 4 2009       no
#> 5 2009      yes
#> 
#> $survey10
#> [1] year     employed
#> <0 rows> (or 0-length row.names)

所需的输出:

$survey08
  year employed
1 2008      yes
2 2008       no
3 2008       no
4 2008      yes
5 2008       no

$survey09
  year employed
1 2009      yes
2 2009      yes
3 2009      yes
4 2009       no
5 2009      yes

$survey10
  year employed
1 2010      2
2 2010      1
3 2010      1
4 2010      1
5 2010      1

reprex软件包 (v0.3.0)创建于2019-08-24

您可以使用purrr::map_at仅修改名称或位置给定的元素。

df_list %>% 
  map_at(c("survey08", "survey09"),
         ~ filter(.x, year %in% 2008:2009)) %>% 
  map_at(c("survey08", "survey09"),
         ~ .x %>% mutate_at(vars(employed), 
         ~ recode_factor(.,`1` = "yes", `2` = "no")))

$`survey08`
  year employed
1 2008      yes
2 2008       no
3 2008       no
4 2008      yes
5 2008       no

$survey09
  year employed
1 2009      yes
2 2009      yes
3 2009      yes
4 2009       no
5 2009      yes

$survey10
  year employed
1 2010        2
2 2010        1
3 2010        1
4 2010        1
5 2010        1

使用filter将删除您要保留的其他data.frame。 您需要map_if而不是map 然后,您可以使用.p来标识要执行地图功能的项目。

df_list %>% 
   map_if(., 
      .f = ~ .x %>% mutate_at(vars(employed), ~recode_factor(.,`1` = "yes", `2` = "no")), 
      .p = c(T,T,F))

要么

df_list %>% 
   map_if(., 
       .f = ~ .x %>% mutate_at(vars(employed), ~recode_factor(.,`1` = "yes", `2` = "no")), 
       .p = ~ .x %>% pull(year) %>% unique(.) %in% 2008:2009)

使用lapply基本R解决方案和用户定义的函数来评估year是否小于2010

df_list2 <- lapply(df_list, function(x){
  if (unique(x$year) < 2010){
    x$employed <- as.character(factor(x$employed, levels = c(1, 2), labels = c("yes", "no")))
  }
  return(x)
})

df_list2
# $survey08
#   year employed
# 1 2008      yes
# 2 2008       no
# 3 2008       no
# 4 2008      yes
# 5 2008       no
# 
# $survey09
#   year employed
# 1 2009      yes
# 2 2009      yes
# 3 2009      yes
# 4 2009       no
# 5 2009      yes
# 
# $survey10
#   year employed
# 1 2010        2
# 2 2010        1
# 3 2010        1
# 4 2010        1
# 5 2010        1

如果您已经知道要执行该操作的列表,为什么不只将其子集并重新编码。

library(tidyverse)

df_list[c("survey08", "survey09")] <- df_list[c("survey08", "survey09")] %>%
  map(~ .x %>% mutate_at(vars(employed), ~recode_factor(.,`1` = "yes", `2` = "no")))


df_list
#$survey08
#  year employed
#1 2008      yes
#2 2008       no
#3 2008       no
#4 2008      yes
#5 2008       no

#$survey09
#  year employed
#1 2009      yes
#2 2009      yes
#3 2009      yes
#4 2009       no
#5 2009      yes

#$survey10
#  year employed
#1 2010        2
#2 2010        1
#3 2010        1
#4 2010        1
#5 2010        1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM