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

时间:2018-12-05 17:05:20

标签: r data-manipulation

我有一个包含家庭住户编号,性别和年龄的数据,如下所示:

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值和旁边的其他列。我想做的就是向显示以下内容的数据框添加新列:

  • “成年女性的数量(性别= 2 &&年龄= 18)”,
  • “成年男性人数(性别= 1,&年龄= 18)”,
  • “小学生人数(6-18岁)”(Num_Sch)和
  • “ preschpol儿童数(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 :(得分: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

希望有帮助。

答案 1 :(得分:0)

您已经在考虑将其很好地转换为逻辑陈述的方式(例如,此人是女性,且年满18岁或以上),因此我将使用一系列逻辑向量来做到这一点,因为/ false表示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包含其端点。您已经将学龄前儿童描述为0到6岁,学龄前儿童是6到18岁。这意味着这6岁的孩子都算在内。您可能想要调整这些端点,这应该不太困难,因为似乎您正在使用age作为整数。