首页 文章

计算满足某些条件的数据框中的行,并按数据框第一列中的唯一值对它们进行分组

提问于
浏览
0

我有一个关于househould id,性别和年龄的数据如下:

mydata <- 

structure(list(ID_HH = c(1,1,1,1,2,2,3,3,3,4,5,5), 
                           GENDER = c(1,2,1,1,1,2,2,1,2,2,1,1), 
                           AGE = c(50,45,3,15,25,5,32,30,10,28,64,16)), 
                      .Names = c("ID", "GENDER", "AGE"), 
                      class = "data.frame", row.names = c(NA, -12L))

   mydata

#  HH_ID GENDER AGE
# 1  1    1    50
# 2  1    2    45
# 3  1    1    3
# 4  1    1    15
# 5  2    1    25
# 6  2    2    5
# 7  3    2    32
# 8  3    1    30
# 9  3    2    10
# 10 4    2    28
# 11 5    1    64
# 12 5    1    16

我有另一个数据帧,我们称之为'输出',它只有唯一的HH_ID值和旁边的其他一些列 . 我想要做的是向此数据框添加新列,显示:

  • "the number of adult females (Gender=2 && Age=18)",

  • "the number of adult males (Gender=1 && Age=18)",

  • "the number of school children (6-18)"(Num_Sch),和

  • "the number of preschpol children (0-6)"(Num_PreSch)

为每个家庭 . 所以'输出'应该是这样的:

#  HH_ID Col1 Col2 ... Num_Fem Num_Male Num_PreSch Num_Sch
# 1  1    ..              1       1         1        1 
# 2  2    ..              0       1         1        0 
# 3  3    ..              1       1         0        1
# 4  4    ..              1       0         0        0
# 5  5    ..              0       1         0        1

我尝试了许多不同的功能和包,但没有什么能达到我想要的 . 我将不胜感激任何帮助或评论 .

2 回答

  • 0

    可能有一种奇特的方法,但您可以使用 for 循环来执行此操作,如下所示:

    mydata  <- as.data.frame(mydata)
    Num_Fem <- Num_Male <- Num_PreSch <- Num_Sch <- c()
    
    for(ID_HH in output$ID_HH){
      curr_HH    <- mydata[mydata$ID_HH == ID_HH,]
    
      Num_Fem    <- c(Num_Fem,    nrow(curr_HH[curr_HH$GENDER==2 & curr_HH$AGE>=18,]))
      Num_Male   <- c(Num_Male,   nrow(curr_HH[curr_HH$GENDER==1 & curr_HH$AGE>=18,]))
      Num_PreSch <- c(Num_PreSch, nrow(curr_HH[curr_HH$AGE<6,]))
      Num_Sch    <- c(Num_Sch,    nrow(curr_HH[curr_HH$AGE>=6 & curr_HH$AGE<18,]))
    }
    
    output <- cbind(output, data.frame(Num_Fem, Num_Male, Num_PreSch, Num_Sch))
    

    它会给你你预期的结果:

    #  HH_ID Col1 Col2 ... Num_Fem Num_Male Num_PreSch Num_Sch
    # 1        1   ..   ..           1        1         1        1 
    # 2        2   ..   ..           0        1         1        0 
    # 3        3   ..   ..           1        1         0        1
    # 4        4   ..   ..           1        0         0        0
    # 5        5   ..   ..           0        1         0        1
    

    希望能帮助到你 .

  • 0

    你已经在考虑这个问题的方式很好地转化为逻辑语句(例如,这个人是女性,18岁或以上),所以我用一系列逻辑向量来做,利用因为真/假翻译的事实到1/0,你可以总结它们 .

    设置不同的类别并为每个类别创建逻辑列 .

    library(tidyverse)
    
    mydata %>%
      mutate(adult_female = (GENDER == 2 & AGE >= 18),
             adult_male = (GENDER == 1 & AGE >= 18),
             school = between(AGE, 6, 18),
             preschool = between(AGE, 0, 6))
    #>    ID GENDER AGE adult_female adult_male school preschool
    #> 1   1      1  50        FALSE       TRUE  FALSE     FALSE
    #> 2   1      2  45         TRUE      FALSE  FALSE     FALSE
    #> 3   1      1   3        FALSE      FALSE  FALSE      TRUE
    #> 4   1      1  15        FALSE      FALSE   TRUE     FALSE
    #> 5   2      1  25        FALSE       TRUE  FALSE     FALSE
    #> 6   2      2   5        FALSE      FALSE  FALSE      TRUE
    #> 7   3      2  32         TRUE      FALSE  FALSE     FALSE
    #> 8   3      1  30        FALSE       TRUE  FALSE     FALSE
    #> 9   3      2  10        FALSE      FALSE   TRUE     FALSE
    #> 10  4      2  28         TRUE      FALSE  FALSE     FALSE
    #> 11  5      1  64        FALSE       TRUE  FALSE     FALSE
    #> 12  5      1  16        FALSE      FALSE   TRUE     FALSE
    

    然后,您可以按家庭分组并将所有类型的逻辑列相加 .

    mydata %>%
      mutate(adult_female = (GENDER == 2 & AGE >= 18),
             adult_male = (GENDER == 1 & AGE >= 18),
             school = between(AGE, 6, 18),
             preschool = between(AGE, 0, 6)) %>%
      group_by(ID) %>%
      summarise_if(is.logical, sum)
    #> # A tibble: 5 x 5
    #>      ID adult_female adult_male school preschool
    #>   <dbl>        <int>      <int>  <int>     <int>
    #> 1     1            1          1      1         1
    #> 2     2            0          1      0         1
    #> 3     3            1          1      1         0
    #> 4     4            1          0      0         0
    #> 5     5            0          1      1         0
    

    我将允许您处理的一个问题:函数 between 包含其 endpoints . 你太难了,因为看起来你正在使用年龄作为整数 .

相关问题