【问题标题】:Create a new variable base on other variables contain a specific value in r基于其他变量创建一个新变量,其中包含 r 中的特定值
【发布时间】:2016-05-03 04:57:49
【问题描述】:

我有几个严重的变量,我想创建两个新的虚拟变量。 变量一:如果其他变量包含特定值,则变量一等于 1。 变量二:如果其他变量连续包含特定值,则变量二等于1。

我的数据看起来像

ID score_2011 score_2012 score_2013 score_2014 score_2015
1          12         15         96         96         16
2          12         15         15         15         16
3          12         96         20         15         16
4          12         15         18         15         16
5          12         15         96         15         16

我想得到如下的新变量

IF score_2011~2015 contain 96 then with_96=1
IF score_2011~2015 contain continuous 96 then back_to_back_96=1 

我希望结果看起来像..

  ID    score_2011 score_2012 score_2013  score_2014  score_2015  with_96  back_to_back_96
    1          12         15         96         96         16       1               1
    2          12         15         15         15         16       0               0
    3          12         96         20         15         16       1               0
    4          12         15         18         15         16       0               0
    5          96         15         96         15         16       1               0

提前致谢

【问题讨论】:

    标签: r variables


    【解决方案1】:

    一种选择是遍历行,查找是否有 any 值是 96('x1'),对每一行进行运行长度编码,检查是否有 any lengths 对于 'TRUE' 值大于 1 ('x2') ,将两者连接,转置并将两个新列分配给输出。

    df1[c("with_96", "back_to_back_96")] <- t(apply(df1[-1], 1, FUN= function(x) {
              x1 <- as.integer(any(x==96))
              rl <- rle(x==96)
              x2 <- any(rl$lengths[rl$values]>1)
              c(x1, x2)}))
    df1
    #  ID score_2011 score_2012 score_2013 score_2014 score_2015 with_96 back_to_back_96
    #1  1         12         15         96         96         16       1               1
    #2  2         12         15         15         15         16       0               0
    #3  3         12         96         20         15         16       1               0
    #4  4         12         15         18         15         16       0               0
    #5  5         12         15         96         15         16       1               0
    

    或者另一个选项是使用rowSums

    df1["with_96"] <- +(!!rowSums(df1[-1]==96))
    df1["back_to_back_96"] <-  rowSums((df1[-c(1, ncol(df1))]==96)  + 
                     (df1[-c(1,2)]==96)>1)
    

    【讨论】:

      【解决方案2】:

      如果您愿意,可以对data.table 进行一些幻想。处理长格式的融合数据集可能会使其中一些比较的逻辑更简单。

      library(data.table)
      setDT(dat)
      melt(dat, id="ID")[, .(with96=any(value==96), b2b96=any(diff(which(value==96))==1)), by=ID]
      
      #   ID with96 b2b96
      #1:  1   TRUE  TRUE
      #2:  2  FALSE FALSE
      #3:  3   TRUE FALSE
      #4:  4  FALSE FALSE
      #5:  5   TRUE FALSE
      

      【讨论】:

      • 谢谢。因为我在数据框中还有其他变量,我如何使用您的代码将第 2 列限制为第 5 列?
      猜你喜欢
      • 1970-01-01
      • 2021-02-10
      • 1970-01-01
      • 2020-09-20
      • 2015-08-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-15
      • 2021-02-09
      相关资源
      最近更新 更多