【问题标题】:wrapping up a long code using loop or similar function使用循环或类似函数包装长代码
【发布时间】:2020-11-20 00:54:07
【问题描述】:

我想知道是否有任何方法可以将下面的代码包装起来以使其更短;我正在考虑使用循环或类似功能来做到这一点。此代码使用 AgeatDeath 和 Disability 生成一个新变量 (cat)。如果 AgeatDeath 介于 75.6 和 77.1 之间并且 Disability 等于“无智力和发育障碍”,则代码创建值为 75.6-77.1 的 cat 变量。 谢谢, 纳德

IDD <- IDD %>%
      mutate(
        cat = case_when(
          AgeatDeath >= 75.6 &
            AgeatDeath < 77.1  &
            Disability == 'No Intelectual and Developmental Disabilities' ~ '75.6-77.1',
          AgeatDeath >= 74.3 &
            AgeatDeath < 75.6  &
            Disability == 'No Intelectual and Developmental Disabilities' ~ '74.3-75.6',
          AgeatDeath >= 72.5 &
            AgeatDeath < 74.3  &
            Disability == 'No Intelectual and Developmental Disabilities' ~ '72.5-74.3',
          AgeatDeath >= 66.5 &
            AgeatDeath < 72.5  &
            Disability == 'No Intelectual and Developmental Disabilities' ~ '66.6-72.5',
          
          AgeatDeath >= 64.1 &
            AgeatDeath < 71.9  &
            Disability == 'Intellectual disability' ~ '64.1-71.9',
          AgeatDeath >= 62.3 &
            AgeatDeath < 64.1  &
            Disability == 'Intellectual disability' ~ '62.3-64.1',
          AgeatDeath >= 59.4 &
            AgeatDeath < 62.3  &
            Disability == 'Intellectual disability' ~ '59.4-62.3',
          AgeatDeath >= 50.4 &
            AgeatDeath < 59.4  &
            Disability == 'Intellectual disability' ~ '50.4-59.4',
          
          AgeatDeath >= 56.47 &
            AgeatDeath < 59.1  &
            Disability == 'Down syndrome' ~ '56.47-59',
          AgeatDeath >= 55.59 &
            AgeatDeath < 56.47  &
            Disability == 'Down syndrome' ~ '55.59-56.47',
          AgeatDeath >= 54.42 &
            AgeatDeath < 55.59  &
            Disability == 'Down syndrome' ~ '54.42-55.59',
          AgeatDeath >= 50.92 &
            AgeatDeath < 54.42  &
            Disability == 'Down syndrome' ~ '50.92-54.42',
          
          AgeatDeath >= 53.3 &
            AgeatDeath < 58.2  &
            Disability == 'Cerebral palsy' ~ '53.3-58.2',
          AgeatDeath >= 50.6 &
            AgeatDeath < 53.3  &
            Disability == 'Cerebral palsy' ~ '50.6-53.3',
          AgeatDeath >= 48.9 &
            AgeatDeath < 50.6  &
            Disability == 'Cerebral palsy' ~ '48.9-50.6',
          AgeatDeath >= 41.38 &
            AgeatDeath < 48.9  &
            Disability == 'Cerebral palsy' ~ '41.4-48.9',
          
          AgeatDeath >= 44.2 &
            AgeatDeath < 51.1  &
            Disability == 'Other rare developmental disabilities' ~ '44.2-51',
          AgeatDeath >= 41.6 &
            AgeatDeath < 44.2  &
            Disability == 'Other rare developmental disabilities' ~ '41.6-44.2',
          AgeatDeath >= 30.6 &
            AgeatDeath < 38.4  &
            Disability == 'Other rare developmental disabilities' ~ '30.6-38.4',
          AgeatDeath >= 38.4 &
            AgeatDeath < 41.6  &
            Disability == 'Other rare developmental disabilities' ~ '38.4-41.6'
        )
      )

【问题讨论】:

    标签: r dplyr case-when


    【解决方案1】:

    一些子集和函数cut() 可以走很长的路。我要演示的内容不涉及dplyr

    首先创建一个空的新变量。我们将使用其余的代码来填充它。

    IDD$cat <- NA_character
    

    接下来,使用Disability 的值和相应的切点创建一个列表。我们将遍历这个列表。

    L <- list(
    `No Intelectual and Developmental Disabilities` = c(66.6, 72.5, 74.3, 75.6, 77.1),
    `Intellectual disability` = c(50.4, 59.4, 62.3, 64.1, 71.9)
    )
    

    您可以填写其余部分。现在,我们将使用循环按Disability 的每个值进行子集化,使用cut() 将值拆分为类别并重命名类别。

    for (d in names(L)) {
       IDD$cat[IDD$Disability == d] <- as.character(
                                          cut(IDD$Ageatdeath, 
                                            breaks = L[[d]], 
                                            labels = paste(L[[d]][-4], L[[d]][-1], sep = "-"),
                                            include.lowest = TRUE,
                                            right = FALSE))
    }
    

    cut() 根据我们提供给L 的断点拆分Ageatdeath。我们根据断点给它标签。 right = FALSE 使得每个类别都包含下限并排除上限,include.lowest = TRUE 确保如果任何值处于上限,则它们包含在最高类别中。我们使用as.character() 来确保它是一个字符向量而不是一个因子。

    【讨论】:

    • 谢谢。我尝试了下面的代码,但它没有捕捉到 AgeatDeath 的一些值,包括 72.01 用于无智力和发育障碍。休息有什么问题:L No Intelectual and Developmental Disabilities = c(66.6, 72.5, 74.3, 75.6, 77.1))
    【解决方案2】:

    无论您采用何种方法,您仍然需要在某处存储阈值和条件。现在这些已写入您的代码中,但可以将它们移动到表格中。

    考虑设置一张桌子

    order | min_age | max_age | disability
    ------+--------+---------+------------
    1     |75.6    | 77.1    | 'No Intelectual and Developmental Disabilities'
    2     |74.3    | 75.6    | 'No Intelectual and Developmental Disabilities'
    etc.
    ...
    

    然后您可以使用表格来设置条件。遵循this问题中的parse_exprs方法:

    # loading of condition table
    # other setup
    # etc.
    
    # ensure conditions are in the preferred order
    twc = table_w_conditions %>%
      arrange(order)
    
    # make text strings of conditions
    conditions = paste("AgeatDeath >=", twc$min_age,
                      "& AgeatDeath <", twc$max_age,
                      "& Disability ==", twc&disability,
                      " ~ '", twc$min_age, "-", twc$max_age, "'")
    
    # mutate treating text strings as code
    IDD <- IDD %>%
      mutate(
            cat = case_when(!!!parse_exprs(conditions))
      )
    

    如果您采用这种方法,我建议您在使用之前查看conditions,以检查它是否包含正确条件文本的文本字符串列表。

    【讨论】:

      猜你喜欢
      • 2023-04-07
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 2014-09-27
      • 1970-01-01
      • 1970-01-01
      • 2014-06-24
      • 1970-01-01
      相关资源
      最近更新 更多