如何评估 R 中 data.frame 中的组内先前值满足的条件

问题描述 投票:0回答:1

我有一个如下所示的数据集:

library(tidyverse)   
 name<-c("AAA","AAA","AAA")
    value<-c(1:3)
    order<-c(2,3,6)
    tag<-c(0,0,0)
    part_a<-data.frame(name,value,order,tag)
    name<-c("AAA","AAA","AAA")
    value<-c(1:3)
    order<-c(1,5,4)
    key<-c(1,1,1)
    part_b<-data.frame(name,value,order,key)
    df<-bind_rows(part_a,part_b)
    df %>% group_by(name) %>% arrange(order)


    Groups:   name [1]
      name  value order   tag   key
      <chr> <int> <dbl> <dbl> <dbl>
    1 AAA       1     1    NA     1
    2 AAA       1     2     0    NA
    3 AAA       2     3     0    NA
    4 AAA       3     4    NA     1
    5 AAA       2     5    NA     1
    6 AAA       3     6     0    NA

我正在尝试编写一个代码,允许我创建两个名为

CHECK_1
CHECK_2
的新变量,
CHECK_1
需要有两个值,如果
tag
列的先前值是 NA,则该值将为 1并且
key
列的先前值不是 NA 和 0,否则,变量 CHECK_2 只需要有两个值,如果
order
列的当前值和先前值之间的差异为“超出范围”,则变量 CHECK_2 应该“超出范围”大于 3 且“在范围内”,否则。

此操作必须在数据框中的组内完成,我知道我可以使用基本 R 函数

lag()
,但我尝试将条件合并到 if_else 语句中,但没有成功。

我想要的输出是:

名字 价值 订购 标签 检查_1 检查_2
AAA 1 1 不适用 1 1 “在范围内”
AAA 1 2 0 不适用 0 “在范围内”
AAA 2 3 0 不适用 0 “在范围内”
AAA 3 4 不适用 1 1 “在范围内”
AAA 2 5 不适用 1 1 “在范围内”
AAA 3 6 0 不适用 0 “在范围内”
r tidyverse data-wrangling
1个回答
2
投票

你可以用

tidyverse
做类似的事情。但是,我不确定您想如何处理该组的第一行值。

library(tidyverse)

df %>% 
  group_by(name) %>% 
  arrange(order) %>% 
  mutate(check_1 = ifelse(is.na(lag(tag)) & !is.na(lag(key)), 1, 0),
         check_2 = ifelse(order - lag(order) > 3, "out of range", "within range"))

输出

  name  value order   tag   key check_1 check_2     
  <chr> <int> <dbl> <dbl> <dbl>   <dbl> <chr>       
1 AAA       1     1    NA     1       0 NA          
2 AAA       1     2     0    NA       1 within range
3 AAA       2     3     0    NA       0 within range
4 AAA       3     4    NA     1       0 within range
5 AAA       2     5    NA     1       1 within range
6 AAA       3     6     0    NA       1 within range

如果您想将第一行值默认为 1 且“在范围内”,那么我们可以使用

case_when
来创建额外的 ifelse 条件。

df %>% 
  group_by(name) %>% 
  arrange(order) %>% 
  mutate(check_1 = case_when(row_number() == 1 ~ 1,
                             is.na(lag(tag)) & !is.na(lag(key)) ~ 1, 
                             TRUE ~ 0),
         check_2 = case_when(row_number() == 1 ~ "within range",
                             order - lag(order) > 3 ~ "out of range", 
                             TRUE ~ "within range"))

  name  value order   tag   key check_1 check_2     
  <chr> <int> <dbl> <dbl> <dbl>   <dbl> <chr>       
1 AAA       1     1    NA     1       1 within range
2 AAA       1     2     0    NA       1 within range
3 AAA       2     3     0    NA       0 within range
4 AAA       3     4    NA     1       0 within range
5 AAA       2     5    NA     1       1 within range
6 AAA       3     6     0    NA       1 within range
© www.soinside.com 2019 - 2024. All rights reserved.