【问题标题】:How to create a new binary variable based on another binary variable in a data frame with the function mutate in R?如何使用 R 中的函数 mutate 基于数据框中的另一个二进制变量创建新的二进制变量?
【发布时间】:2020-07-26 03:38:08
【问题描述】:

数据框df有2个变量---第一列是id,第二列是女士英语水平(lep)。 现在,我想使用规则创建一个名为 sign 的新列----如果 lep 变量中的第一个 1 和最后一个 1 之间有零,则 sign=1,否则 sign=0。任何帮助将不胜感激!

structure(list(id = c(3831001, 3831001, 3831001, 3831001, 3831001, 
3831001, 3831001, 3831001, 3831002, 3831002, 3831002, 3831002, 
3831002, 3831002, 3831002, 3831002, 3831003, 3831003, 3831003, 
3831003, 3831003, 3831003, 3831003, 3831003, 3831004, 3831004, 
3831004, 3831004, 3831004, 3831004, 3831005, 3831005, 3831005, 
3831005, 3831005, 3831005, 3831005, 3831006, 3831006, 3831006, 
3831006, 3831006, 3831006, 3831007, 3831007, 3831007, 3831007, 
3831007, 3831007, 3831007, 3831007), lep = c(1, 1, 1, NA, NA, 
0, NA, 0, 1, 1, 0, 1, 0, 0, NA, 1, 1, 0, 0, 0, NA, 1, 0, NA, 
1, 0, NA, 1, 0, NA, 1, NA, NA, 0, NA, NA, 1, 1, 0, NA, 0, 0, 
0, 1, 0, 0, 0, 0, NA, NA, 1)), row.names = c(NA, -51L), groups = structure(list(
    id = c(3831001, 3831002, 3831003, 3831004, 3831005, 3831006, 
    3831007), .rows = structure(list(1:8, 9:16, 17:24, 25:30, 
        31:37, 38:43, 44:51), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = c(NA, 7L), class = c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))->df

#.The expected result is as follows,
id        lep sign

3831001    1   0

3831001    1   0

3831001    1   0

3831001    NA  0

3831001    NA  0

3831001    0   0

3831001    NA  0

3831001    0   0

3831002    1   1

3831002    0   1

3831002    0   1

3831002    1   1

3831002    0   1

3831002    0   1

3831002    NA  1

3831002    1   1

...............

3831006    1   0

3831006    0   0

3831006    NA  0

3831006    0   0

3831006    0   0

3831006    0   0

3831007    1   1

3831007    0   1

3831007    0   1

3831007    0   1

3831007    0   1

3831007    NA  1

3831007    NA  1

3831007    1   1

【问题讨论】:

  • 我对这两个答案都很满意。然而,似乎所有候选人中只有一个选择,让提问者很尴尬。

标签: r


【解决方案1】:

我们可以通过data.table 做到这一点。将 'data.frame' 转换为 'data.table' (setDT),按 'id' 分组,用which 得到逻辑向量 (lep == 1) 的位置索引,然后是最小值和最大值从range得到的位置,得到Reduce内的序列(:),用它作为索引得到相应的'lep'值,检查是否有0%in%,转换为整数(@ 987654329@) 并将其分配给 (:=) 'sign' 列

library(data.table)
setDT(df)[, # // convert to data.table
    sign :=  # // assign to new column
         +( # // coerce logical to binary
           0 %in% # // check if 0 is there in the subset of lep
             lep[ # // extract the lep elements based on index
                Reduce(`:`, # // get the sequence 
                   range( # // returns the min and max of position index
                        which(lep == 1) # // returns the position index
                   ))]),
               by = id] # // grouped by ID
df
#         id lep sign
# 1: 3831001   1    0
# 2: 3831001   1    0
# 3: 3831001   1    0
# 4: 3831001  NA    0
# 5: 3831001  NA    0
# 6: 3831001   0    0
# 7: 3831001  NA    0
# 8: 3831001   0    0
# 9: 3831002   1    1
#10: 3831002   1    1
#11: 3831002   0    1
#12: 3831002   1    1
#13: 3831002   0    1
#14: 3831002   0    1
#15: 3831002  NA    1
#16: 3831002   1    1
# ...

【讨论】:

    【解决方案2】:

    对于每个id,您可以获得max 和min 的索引,其中lep = 1 并且如果它们之间的任何值是0,则返回1。

    library(dplyr)
    df %>%
      group_by(id) %>%
      mutate(sign = {inds <- which(lep == 1);
                     as.integer(any(lep[min(inds):max(inds)] == 0))})
    
    #       id   lep  year  flag  sign
    #     <dbl> <dbl> <dbl> <dbl> <int>
    # 1 3831001     1     1     0     0
    # 2 3831001     1     2     0     0
    # 3 3831001     1     3     1     0
    # 4 3831001    NA     4     0     0
    # 5 3831001    NA     5     0     0
    # 6 3831001     0     6     0     0
    # 7 3831001    NA     7     0     0
    # 8 3831001     0     8     0     0
    # 9 3831002     1     1     0     1
    #10 3831002     1     2     0     1
    # … with 41 more rows
    

    【讨论】:

      猜你喜欢
      • 2021-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 2019-09-28
      • 1970-01-01
      • 2020-10-20
      相关资源
      最近更新 更多