【问题标题】:R - Create new variable based on certain conditionsR - 根据特定条件创建新变量
【发布时间】:2020-07-01 15:07:23
【问题描述】:

我有以下数据框df,其中包含长格式的纵向数据(见下文)。我想根据某些条件创建一个名为 new.var 的新变量。如果一个人的 postLin 的第一个值 > 0 但 并且 preLin 的值 == 0,则此新变量应为 1。 new.var 每人最多只能有一个 1 (ID)。

df <- read.table(text=
"ID       preLin   postLin      
800057    -8.55    0               
800057    -6.34    0           
800057    -5.34    0           
800057    -4.34    0         
800057        0    0.33   
800119    -0.88    0  
800119        0    0           
800119        0    1       
834011     -4.1    0 
834011     -3.1    0   
834341        0    1.34 
834341        0    2.34   
834341        0    3.34   
834341        0    5.34    
834341        0    6.66  
800125        0    0
800125        0    2.14
897177    -0.33    0 
897177        0    0.67 
897177        0    1.67", header=TRUE)

首先,我尝试了这段代码:

df$new.var1 <- ifelse(df$preLin == 0 & (df$postLin >= 0 & df$postLin <= 1), 1, 0)

但是,对于 ID 800119,将有两个 1。

我的预期结果是这样的:

df_new <- read.table(text=
"ID       preLin   postLin    new.var  
800057    -8.55    0          0         
800057    -6.34    0          0  
800057    -5.34    0          0
800057    -4.34    0          0     
800057        0    0.33       1 
800119    -0.88    0          0 
800119        0    0          1  
800119        0    1          0
834011     -4.1    0          0 
834011     -3.1    0          0 
834341        0    1.34       0
834341        0    2.34       0
834341        0    3.34       0  
834341        0    5.34       0    
834341        0    6.66       0
800125        0    0          1
800125        0    2.14       0
897177    -0.33    0          0
897177        0    0.67       1
897177        0    1.67       0", header=TRUE) 

有人知道我的问题的解决方案吗?非常感谢!

【问题讨论】:

  • 但是您应该为 800119 的第三个实例的 new.var 获得 1。这是该行的正确值,因为 preLin 是 0,postLin 是>= 0 和
  • 只有当我的条件第一次满足时,new.var 才应该是 1。因此,只有 800119 的第二个实例应该得到 1 而不是第三个实例。

标签: r dplyr


【解决方案1】:

您的预期结果来自于在ifelse 中声明条件如下:

df$new.var1 <- ifelse((df$postLin > 0 & df$postLin < 1) | (df$preLin == 0 & df$postLin ==0), 1, 0)

value = 1 如果 df$postLin 的值介于 0 和 1 之间(但不是 0 和 1) 如果 df$preLin 和 df$postLin 都为 0。否则 值 = 0

结果:

       ID preLin postLin new.var1
1  800057  -8.55    0.00        0
2  800057  -6.34    0.00        0
3  800057  -5.34    0.00        0
4  800057  -4.34    0.00        0
5  800057   0.00    0.33        1
6  800119  -0.88    0.00        0
7  800119   0.00    0.00        1
8  800119   0.00    1.00        0
9  834011  -4.10    0.00        0
10 834011  -3.10    0.00        0
11 834341   0.00    1.34        0
12 834341   0.00    2.34        0
13 834341   0.00    3.34        0
14 834341   0.00    5.34        0
15 834341   0.00    6.66        0
16 800125   0.00    0.00        1
17 800125   0.00    2.14        0
18 897177  -0.33    0.00        0
19 897177   0.00    0.67        1
20 897177   0.00    1.67        0

备注:保持条件为 将导致在第三个 800119 中增加一个,正如@shirewoman2 在她的评论中所说的那样

【讨论】:

    【解决方案2】:

    这是一种使用tidyverse 的方法。它将您的 IDs and uses the filter you want. A little helper columns is build which finds the first occurence in postLin, it is removed later. mutatewithifelse applies your rules. Then the result is joined with the original DF and NAs 分组为零。

    library(tidyverse)
    
    
    df %>%
      group_by(ID) %>%
      dplyr::filter(postLin > 0 | (postLin == 0 & preLin == 0)) %>%
      dplyr::mutate(
        first = dplyr::first(postLin)
      ) %>%
      mutate(new.var = ifelse((postLin == first & postLin < 1), 1, 0)) %>%
      select(-c(first)) %>%
      right_join(df, by = c("ID", "preLin", "postLin")) %>%
      mutate(new.var = ifelse(is.na(new.var), 0, new.var)) %>%
      arrange(ID, preLin, postLin)
    #> # A tibble: 20 x 4
    #> # Groups:   ID [6]
    #>        ID preLin postLin new.var
    #>     <int>  <dbl>   <dbl>   <dbl>
    #>  1 800057  -8.55    0          0
    #>  2 800057  -6.34    0          0
    #>  3 800057  -5.34    0          0
    #>  4 800057  -4.34    0          0
    #>  5 800057   0       0.33       1
    #>  6 800119  -0.88    0          0
    #>  7 800119   0       0          1
    #>  8 800119   0       1          0
    #>  9 800125   0       0          1
    #> 10 800125   0       2.14       0
    #> 11 834011  -4.1     0          0
    #> 12 834011  -3.1     0          0
    #> 13 834341   0       1.34       0
    #> 14 834341   0       2.34       0
    #> 15 834341   0       3.34       0
    #> 16 834341   0       5.34       0
    #> 17 834341   0       6.66       0
    #> 18 897177  -0.33    0          0
    #> 19 897177   0       0.67       1
    #> 20 897177   0       1.67       0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-07
      • 2022-08-13
      相关资源
      最近更新 更多