如果多个组满足某些条件,如何更改后续的行值?

时间:2019-02-22 17:26:39

标签: r dataframe

我有一个看起来像这样的数据框:

awk '{
    for (i=1; i <= $3/2; i++)
        for (j=1; j<=2; j++)
            print $1,$2,"Bj"i,"??????"
}' OFS="\t" testt

我想在满足条件时更改ID名称,并也更改后面的ID名称。每个ID可以多次满足该条件,因此我想每次对其进行修改。

结果将更改原始ID或仅添加新列:

ID  value   condition
A   0         0
A   3         0
A   0         1
A   7         1
A   5         0
A   5         0
A   5         0
A   7         0
B   6         0
B   2         1
B   7         0
B   10        1
B   0         0
B   6         0

4 个答案:

答案 0 :(得分:6)

按“ ID”分组后的一个选项,使用{{1}创建索引(来自rleid),并根据条件{{1}将其更改为data.table“ ID” }}

paste

数据

case_when

答案 1 :(得分:3)

与@akrun相同,但仅使用data.table

library(data.table)
setDT(df)

df[, newID := paste0(ID, gsub('^0$', '', rleid(condition) - 1)), ID]
df
#     ID value condition newID
#  1:  A     0         0     A
#  2:  A     3         0     A
#  3:  A     0         1    A1
#  4:  A     7         1    A1
#  5:  A     5         0    A2
#  6:  A     5         0    A2
#  7:  A     5         0    A2
#  8:  A     7         0    A2
#  9:  B     6         0     B
# 10:  B     2         1    B1
# 11:  B     7         0    B2
# 12:  B    10         1    B3
# 13:  B     0         0    B4
# 14:  B     6         0    B4

答案 2 :(得分:2)

还可以:

library(dplyr)

df %>%
  group_by(ID) %>%
  mutate(newID = cumsum(c(0, (condition != lag(condition))[-1])),
         newID = ifelse(newID != 0, paste0(ID, newID), ID))

输出:

# A tibble: 14 x 4
# Groups:   ID [2]
   ID    value condition newID
   <chr> <int>     <int> <chr>
 1 A         0         0 A    
 2 A         3         0 A    
 3 A         0         1 A1   
 4 A         7         1 A1   
 5 A         5         0 A2   
 6 A         5         0 A2   
 7 A         5         0 A2   
 8 A         7         0 A2   
 9 B         6         0 B    
10 B         2         1 B1   
11 B         7         0 B2   
12 B        10         1 B3   
13 B         0         0 B4   
14 B         6         0 B4  

答案 3 :(得分:0)

如果我理解正确,OP将为ID的每个连续条纹在每个condition中创建子组。

不幸的是,OP要求以特殊方式命名子组,这使得解决方案过于复杂。根据OP的要求,将对子组进行命名,例如A, A1, A2,这意味着子组编号和子组名称被一个偏移,例如,第二个子组命名为A1,第三个子组命名为{{1 }}等

如果可以接受更简化的命名方案,我们可以直接受益于A2函数的prefix参数。然后,组rleid()的第一个子组将被命名为A,第二个A1,以此类推。

dplyr

A2
library(dplyr)
df %>% 
  group_by(ID) %>% 
  mutate(newID = data.table::rleid(condition, prefix = first(ID)))

data.table

# A tibble: 14 x 4
# Groups:   ID [2]
   ID    value condition newID
   <chr> <int>     <int> <chr>
 1 A         0         0 A1   
 2 A         3         0 A1   
 3 A         0         1 A2   
 4 A         7         1 A2   
 5 A         5         0 A3   
 6 A         5         0 A3   
 7 A         5         0 A3   
 8 A         7         0 A3   
 9 B         6         0 B1   
10 B         2         1 B2   
11 B         7         0 B3   
12 B        10         1 B4   
13 B         0         0 B5   
14 B         6         0 B5
library(data.table)
setDT(df)[, newID := rleid(condition, prefix = ID), ID][]

数据

    ID value condition newID
 1:  A     0         0    A1
 2:  A     3         0    A1
 3:  A     0         1    A2
 4:  A     7         1    A2
 5:  A     5         0    A3
 6:  A     5         0    A3
 7:  A     5         0    A3
 8:  A     7         0    A3
 9:  B     6         0    B1
10:  B     2         1    B2
11:  B     7         0    B3
12:  B    10         1    B4
13:  B     0         0    B5
14:  B     6         0    B5