使用purrr以编程方式创建新变量?

蒂尔南

介绍

在最近参加Hadley Wickham的函数式编程课程之后,我决定尝试将一些课程应用于我在工作中的项目。自然,事实证明,我尝试的第一个项目比课堂上演示的示例更加复杂。是否有人建议使用该purrr软件包以使下面描述的任务更有效率?

项目背景

我需要将五分位数组分配给空间多边形数据框中的记录。除了记录标识符外,还有其他几个变量,我需要为每个变量计算五分位数组。

这是问题的症结所在:我被要求找出一个特定变量中的离群值,并在整个分析中忽略那些记录,只要它不会改变任何其他变量的第一个五分位数组的五分位数组成

问题

我已经组合了一个dplyr管道(请参见下面的示例),该管道对单个变量执行此检查过程,但是如何重新编写此过程,以便可以有效地检查每个变量?

编辑:虽然可以通过中间步骤将数据的形状从宽变长,但是最终它需要返回其宽格式,以使其与@polygons空间多边形数据框插槽匹配

可重现的例子

您可以在此处找到完整的脚本:https : //gist.github.com/tiernanmartin/6cd3e2946a77b7c9daecb51aa11e0c94

库和设置

library(grDevices)      # boxplot.stats()
library(operator.tools) # %!in% logical operator
library(tmap)           # 'metro' data set
library(magrittr)       # piping
library(dplyr)          # exploratory data analysis verbs
library(purrr)          # recursive mapping of functions 
library(tibble)         # improved version of a data.frame
library(ggplot2)        # dot plot
library(ggrepel)        # avoid label overlap

options(scipen=999)
set.seed(888)

加载示例数据并获取其中的一小部分

data("metro")
    
m_spdf <- metro
# Take a sample
m <-  
        metro@data %>% 
        as_tibble %>% 
        select(-name_long,-iso_a3) %>% 
        sample_n(50)

> m
# A tibble: 50 x 10
          name pop1950 pop1960 pop1970 pop1980 pop1990
         <chr>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1       Sydney 1689935 2134673 2892477 3252111 3631940
2       Havana 1141959 1435511 1779491 1913377 2108381
3     Campinas  151977  293174  540430 1108903 1693359
4         Kano  123073  229203  541992 1349646 2095384
5         Omsk  444326  608363  829860 1032150 1143813
6  Ouagadougou   33035   59126  115374  265200  537441
7    Marseille  755805  928768 1182048 1372495 1418279
8      Taiyuan  196510  349535  621625 1105695 1636599
9       La Paz  319247  437687  600016  809218 1061850
10   Baltimore 1167656 1422067 1554538 1748983 1848834
# ... with 40 more rows, and 4 more variables:
#   pop2000 <dbl>, pop2010 <dbl>, pop2020 <dbl>,
#   pop2030 <dbl>

计算有无异常记录的五分位数组

# Calculate the quintile groups for one variable (e.g., `pop1990`)
m_all <- 
        m %>% 
        mutate(qnt_1990_all = dplyr::ntile(pop1990,5))

# Find the outliers for a different variable (e.g., 'pop1950')
# and subset the df to exlcude these outlier records
m_out <- boxplot.stats(m$pop1950) %>% .[["out"]]
        
m_trim <- 
        m %>% 
        filter(pop1950 %!in% m_out) %>% 
        mutate(qnt_1990_trim = dplyr::ntile(pop1990,5))

# Assess whether the outlier trimming impacted the first quintile group
m_comp <- 
        m_trim %>% 
        select(name,dplyr::contains("qnt")) %>% 
        left_join(m_all,.,"name") %>% 
        select(name,dplyr::contains("qnt"),everything()) %>% 
        mutate(qnt_1990_chng_lgl = !is.na(qnt_1990_trim) & qnt_1990_trim != qnt_1990_all,
               qnt_1990_chng_dir = if_else(qnt_1990_chng_lgl,
                                           paste0(qnt_1990_all," to ",qnt_1990_trim),
                                           "No change"))

在一点协助下ggplot2,我可以看到在这个例子中,确定了6个离群点,并且他们的遗漏并没有影响到第一个五分位数的群体pop1990

受异常值删除影响的记录

重要的是,此信息在两个新变量中进行了跟踪:qnt_1990_chng_lglqnt_1990_chng_dir

> m_comp %>% select(name,qnt_1990_chng_lgl,qnt_1990_chng_dir,everything())
# A tibble: 50 x 14
          name qnt_1990_chng_lgl qnt_1990_chng_dir qnt_1990_all qnt_1990_trim
         <chr>             <lgl>             <chr>        <dbl>         <dbl>
1       Sydney             FALSE         No change            5            NA
2       Havana              TRUE            4 to 5            4             5
3     Campinas              TRUE            3 to 4            3             4
4         Kano             FALSE         No change            4             4
5         Omsk             FALSE         No change            3             3
6  Ouagadougou             FALSE         No change            1             1
7    Marseille             FALSE         No change            3             3
8      Taiyuan              TRUE            3 to 4            3             4
9       La Paz             FALSE         No change            2             2
10   Baltimore             FALSE         No change            4             4
# ... with 40 more rows, and 9 more variables: pop1950 <dbl>, pop1960 <dbl>,
#   pop1970 <dbl>, pop1980 <dbl>, pop1990 <dbl>, pop2000 <dbl>, pop2010 <dbl>,
#   pop2020 <dbl>, pop2030 <dbl>

我现在需要找到一种方法来对数据帧中的每个变量(即pop1960- pop2030重复此过程理想情况下,将为每个现有pop*变量创建两个新变量,并在它们的名称之前qnt_或之后加上_chng_dir_chng_lgl

purrr用于此的正确工具吗?dplyr::mutate_data.table

蒂尔南

事实证明,使用+ +函数可以解决此问题尽管@shayaa和@Gregor没有提供我想要的解决方案,但他们的建议帮助我从正在研究的函数式编程方法中正确地进行了修正。tidyr::gatherdplyr::group_bytidyr::spread

我最终使用@shayaagathergroup_by组合,然后mutate创建变量名(qnt_*_chng_lglqnt_*_chng_dir),然后使用spread再次将其变宽。传递了一个匿名函数,以summarize_all删除由NAlong-long-wide-wide转换创建的所有多余的。

m_comp <- 
        m %>% 
        mutate(qnt = dplyr::ntile(pop1950,5)) %>%
        filter(pop1950 %!in% m_out) %>% 
        gather(year,pop,-name,-qnt) %>% 
        group_by(year) %>% 
        mutate(qntTrim = dplyr::ntile(pop,5),
               qnt_chng_lgl = !is.na(qnt) & qnt != qntTrim,
               qnt_chng_dir = ifelse(qnt_chng_lgl,
                                     paste0(qnt," to ",qntTrim),
                                     "No change"),
               year_lgl = paste0("qnt_chng_",year,"_lgl"),
               year_dir = paste0("qnt_chng_",year,"_dir")) %>% 
        spread(year_lgl,qnt_chng_lgl) %>% 
        spread(year_dir,qnt_chng_dir) %>% 
        spread(year,pop) %>% 
        select(-qnt,-qntTrim) %>% 
        group_by(name) %>% 
        summarize_all(function(.){subset(.,!is.na(.)) %>% first}) 

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在Woocommerce中以编程方式创建新订单

来自分类Dev

Surveymonkey以编程方式创建新调查?

来自分类Dev

以编程方式创建新的UI元素

来自分类Dev

以编程方式在新选项卡中创建新的QTextEdit

来自分类常见问题

如何使用Swift以编程方式创建UILabel?

来自分类Dev

以编程方式使用NSTextView创建窗口

来自分类Dev

如何使用内容以编程方式创建UIImage

来自分类Dev

使用VBA以编程方式创建PowerPoint布局?

来自分类Dev

无法以编程方式使用Gridlayout创建视图

来自分类Dev

使用JsZip以编程方式创建zip文件

来自分类Dev

如何检查我是否正在以编程方式创建新实例?

来自分类Dev

跨系统缓存-以编程方式创建新类

来自分类Dev

solr-以编程方式创建一个新集合

来自分类Dev

如何通过mapbox api以编程方式创建新的mapbox样式?

来自分类Dev

以编程方式在AWS Elastic Beanstalk中创建新实例

来自分类Dev

从功能上以编程方式创建新表格

来自分类Dev

SQL Web复制,以编程方式创建新的订阅

来自分类Dev

跨系统缓存-以编程方式创建新类

来自分类Dev

在样式表中以编程方式创建新的CSS规则

来自分类Dev

导出到Excel:以编程方式创建新的Excel工作表

来自分类Dev

以编程方式在edittext下创建一个新的textview

来自分类Dev

以编程方式创建控制器的新实例

来自分类Dev

Applozic SDK,无法以编程方式创建新组

来自分类Dev

在 Umbraco 8 中以编程方式创建新的内容节点

来自分类Dev

以编程方式替换变量

来自分类Dev

以编程方式声明变量

来自分类Dev

使用 mutate 编程以创建新的数据列

来自分类Dev

以编程方式创建UITableViewCells

来自分类Dev

以编程方式创建dataList

Related 相关文章

热门标签

归档