R创建一列以标识该行属于

时间:2018-02-06 18:17:01

标签: r dataframe dplyr grouping

数据描述:数据集包含有关用户年龄,性别和所持会员资格的信息。

目标:根据预定义的条件创建新列以标识每个用户的组/标签。

年龄条件:多个年龄段:

18 >= age <= 24, 25 >= age <=30, 31 >= age <= 41, 41 >= age <= 60, age >= 61

Gender: M/F

Membership: A,B,C,I

我创建了样本数据框,尝试创建新列以识别组/标签

df = data.frame(userid = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11, 12), 
                 age = c(18, 61, 23, 35, 30, 25, 55, 53, 45, 41, 21, NA),
                 gender = c('F', 'M', 'F', 'F', 'M', 'M', 'M', 'M', 'M', 'F', '<NA>', 'M'),
                 membership = c('A', 'B', 'A', 'C', 'C', 'B', 'A', 'A', 'I', 'I', 'A', '<NA>'))

   userid age gender membership
1       1  18      F          A
2       2  61      M          B
3       3  23      F          A
4       4  35      F          C
5       5  30      M          C
6       6  25      M          B
7       7  55      M          A
8       8  53      M          A
9       9  45      M          I
10     10  41      F          I
11     11  21   <NA>          A
12     12  NA      M       <NA>

根据以上数据,存在4 * 2 * 5个选项(组合)

最终结果:

   userid age gender membership GroupID
1       1  16      F          A    1
2       2  61      M          B   40
3       3  23      F          A    1
4       4  35      F          C    4
5       5  30      M          C    5
6       6  25      M          B    3
7       7  55      M          A   32
8       8  53      M          A   32
9       9  45      M          I   34 
10     10  41      F          I   35

   userid age gender membership  GroupID
1       1  18      F          A    1
2       2  61      M          B   40 
3       3  23      F          A    1
4       4  35      F          C    4
5       5  30      M          C    5
6       6  25      M          B    3
7       7  55      M          A   32
8       8  53      M          A   32
9       9  45      M          I   34
10     10  41      F          I   35
11     11  21   <NA>          A   43 (assuming it will auto-detec combo)
12     12  NA      M       <NA>   46

我相信我的组合计算是正确的,如果是这样,我如何使用dplyr或任何其他选项来获得上面的数据框。

使用多个if条件确认所有选项?

dplyr中有一种方法可以为每列实际提供条件来设置分组条件:

df %>% group_by(age, gender, membership)

3 个答案:

答案 0 :(得分:1)

两个选项,

一个,更加自动化;

# install.packages(c("tidyverse""), dependencies = TRUE)
library(tidyverse)   
df %>% mutate(ageCat = cut(age, breaks = c(-Inf, 24, 30, 41, 60, Inf))) %>%
     mutate(GroupID = group_indices(., ageCat, gender, membership)) %>% select(-ageCat)
#>    userid age gender membership GroupID
#> 1       1  18      F          A      2
#> 2       2  61      M          B      9
#> 3       3  23      F          A      2
#> 4       4  35      F          C      5
#> 5       5  30      M          C      4
#> 6       6  25      M          B      3
#> 7       7  55      M          A      7
#> 8       8  53      M          A      7
#> 9       9  45      M          I      8
#> 10     10  41      F          I      6
#> 11     11  21   <NA>          A      1
#> 12     12  NA      M       <NA>     10

两个,更多手册;

这里我举例说明了类别为14的解决方案,您必须自己编写其余的代码。

df %>% mutate(GroupID = 
  ifelse((age >= 18 | age > 25) & gender == 'F' & membership == "A", 1, 
  ifelse((age >= 31 | age > 41) & gender == 'F' & membership == "C", 4, NA)
              ))
#>    userid age gender membership GroupID
#> 1       1  18      F          A       1
#> 2       2  61      M          B      NA
#> 3       3  23      F          A       1
#> 4       4  35      F          C       4
#> 5       5  30      M          C      NA
#> 6       6  25      M          B      NA
#> 7       7  55      M          A      NA
#> 8       8  53      M          A      NA
#> 9       9  45      M          I      NA
#> 10     10  41      F          I      NA
#> 11     11  21   <NA>          A      NA
#> 12     12  NA      M       <NA>      NA

数据结构以防其他人感觉好像放手一搏,

答案 1 :(得分:1)

如果您只想使用基础R,您可以执行以下操作:

# 1
allcombos <- expand.grid(c("M", "F"), c("A", "B", "C", "I"), 1:5)
allgroups <- do.call(paste0, allcombos)   # 40 unique combinations

# 2
agegroups <- cut(df$age, 
               breaks = c(17, 24, 30, 41, 61, 99), 
               labels = c(1, 2, 3, 4, 5))
# 3
df$groupid <- paste0(df$gender, df$membership, agegroups)
df$groupid <- factor(df$groupid, levels=allgroups, labels=1:length(allgroups))
  1. expand.grid为您提供了一个包含三列的data.frame,其中每一行代表所提供的三个参数的唯一组合。如你所说,这些是40种组合。第二行将数据框的每一行组合在一个字符串中,如"MA1", "FA1", "MB1", etc
  2. 然后我们将cut用于每个年龄段,并使用名称为1到5的相关年龄组。
  3. 我们在df中创建了一个列,其中包含性别,成员资格和年龄组的三个字符组合,然后根据我们在allgroups中找到的所有可能组合将其转换为因子。

答案 2 :(得分:1)

你可以试试这个:

setDT(df)[,agegrp:= ifelse((df$age >= 18)  & (df$age <= 24), 1, ifelse((df$age >= 25)  & (df$age <= 30), 2, ifelse((df$age >= 31)  & (df$age <= 41),3,ifelse((df$age >= 42)  & (df$age <= 60),4,5))))]
setDT(df)[, group := .GRP, by = .(agegrp,gender, membership)]