как увеличить значение переменной для каждой строки

avatar
Patrick Parts
1 июля 2021 в 15:59
77
4
0

У меня есть этот кадр данных,

dat= rep(c("A", "B", "C"),3)
tat=c(rep("ttt", 6), rep("aaa", 6), rep("ddd", 6))
pct=c(14,7,12,8,11,13,19,6,9,11,13,20,11,18,6,9,10,13)
data=data.frame(dat, tat, pct) %>% group_by(tat) %>% mutate(max= max(pct))

> data
# A tibble: 18 x 4
# Groups:   tat [3]
   dat   tat     pct   max
   <chr> <chr> <dbl> <dbl>
 1 A     ttt      14    14
 2 B     ttt       7    14
 3 C     ttt      12    14
 4 A     ttt       8    14
 5 B     ttt      11    14
 6 C     ttt      13    14
 7 A     aaa      19    20
 8 B     aaa       6    20
 9 C     aaa       9    20
10 A     aaa      11    20
11 B     aaa      13    20
12 C     aaa      20    20
13 A     ddd      11    18
14 B     ddd      18    18
15 C     ddd       6    18
16 A     ddd       9    18
17 B     ddd      10    18
18 C     ddd      13    18

И я хотел бы создать еще одну переменную, которая увеличивала бы значение max на 1 для каждой строки (группировка по переменной tat). Пожалуйста, найдите пример моей палочки ниже. Есть ли у кого-нибудь идея сделать это?

> data2
# A tibble: 18 x 5
# Groups:   tat [3]
   dat   tat     pct   max  ...5
   <chr> <chr> <dbl> <dbl> <dbl>
 1 A     ttt      14    14    14
 2 B     ttt       7    14    15
 3 C     ttt      12    14    16
 4 A     ttt       8    14    17
 5 B     ttt      11    14    18
 6 C     ttt      13    14    19
 7 A     aaa      19    20    20
 8 B     aaa       6    20    21
 9 C     aaa       9    20    22
10 A     aaa      11    20    23
11 B     aaa      13    20    24
12 C     aaa      20    20    25
13 A     ddd      11    18    18
14 B     ddd      18    18    19
15 C     ddd       6    18    20
16 A     ddd       9    18    21
17 B     ddd      10    18    22
18 C     ddd      13    18    23


Источник

Ответы (4)

avatar
Karthik S
1 июля 2021 в 16:02
2

Работает ли это:

library(dplyr)

data %>% group_by(tat) %>% mutate(c5 = max + row_number() - 1)
# A tibble: 18 x 5
# Groups:   tat [3]
   dat   tat     pct   max    c5
   <chr> <chr> <dbl> <dbl> <dbl>
 1 A     ttt      14    14    14
 2 B     ttt       7    14    15
 3 C     ttt      12    14    16
 4 A     ttt       8    14    17
 5 B     ttt      11    14    18
 6 C     ttt      13    14    19
 7 A     aaa      19    20    20
 8 B     aaa       6    20    21
 9 C     aaa       9    20    22
10 A     aaa      11    20    23
11 B     aaa      13    20    24
12 C     aaa      20    20    25
13 A     ddd      11    18    18
14 B     ddd      18    18    19
15 C     ddd       6    18    20
16 A     ddd       9    18    21
17 B     ddd      10    18    22
18 C     ddd      13    18    23
Patrick Parts
1 июля 2021 в 16:08
0

Да !! это именно то, что я хотел, и я чувствую себя глупо, что это было так просто!!

avatar
ThomasIsCoding
1 июля 2021 в 20:00
1

Базовый вариант R с использованием ave + seq_along

> transform(
+     data,
+     c5 = ave(max, tat, FUN = seq_along) - 1 + max
+ )
   dat tat pct max c5
1    A ttt  14  14 14
2    B ttt   7  14 15
3    C ttt  12  14 16
4    A ttt   8  14 17
5    B ttt  11  14 18
6    C ttt  13  14 19
7    A aaa  19  20 20
8    B aaa   6  20 21
9    C aaa   9  20 22
10   A aaa  11  20 23
11   B aaa  13  20 24
12   C aaa  20  20 25
13   A ddd  11  18 18
14   B ddd  18  18 19
15   C ddd   6  18 20
16   A ddd   9  18 21
17   B ddd  10  18 22
18   C ddd  13  18 23
avatar
akrun
1 июля 2021 в 16:50
1

Использование data.table

library(data.table)
setDT(data)[, c5 := max + (seq_len(.N) - 1), tat]
> data
    dat tat pct max c5
 1:   A ttt  14  14 14
 2:   B ttt   7  14 15
 3:   C ttt  12  14 16
 4:   A ttt   8  14 17
 5:   B ttt  11  14 18
 6:   C ttt  13  14 19
 7:   A aaa  19  20 20
 8:   B aaa   6  20 21
 9:   C aaa   9  20 22
10:   A aaa  11  20 23
11:   B aaa  13  20 24
12:   C aaa  20  20 25
13:   A ddd  11  18 18
14:   B ddd  18  18 19
15:   C ddd   6  18 20
16:   A ddd   9  18 21
17:   B ddd  10  18 22
18:   C ddd  13  18 23
avatar
Benjamin Christoffersen
1 июля 2021 в 16:20
2

Когда переменная отсортирована по, в базе R 4.1.0 или выше вы можете сделать следующее:

datf |> within(
  max_plus <- unlist(tapply(pct, factor(tat, unique(tat)), 
                            function(x) max(x) + seq_along(x) - 1)))
#R>    dat tat pct max_plus
#R> 1    A ttt  14       14
#R> 2    B ttt   7       15
#R> 3    C ttt  12       16
#R> 4    A ttt   8       17
#R> 5    B ttt  11       18
#R> 6    C ttt  13       19
#R> 7    A aaa  19       20
#R> 8    B aaa   6       21
#R> 9    C aaa   9       22
#R> 10   A aaa  11       23
#R> 11   B aaa  13       24
#R> 12   C aaa  20       25
#R> 13   A ddd  11       18
#R> 14   B ddd  18       19
#R> 15   C ddd   6       20
#R> 16   A ddd   9       21
#R> 17   B ddd  10       22
#R> 18   C ddd  13       23

После ответа onyambu в комментариях вы можете использовать ave:

dat= rep(c("A", "B", "C"),3)
tat=c(rep("ttt", 6), rep("aaa", 6), rep("ddd", 6))
pct=c(14,7,12,8,11,13,19,6,9,11,13,20,11,18,6,9,10,13)
datf <- data.frame(dat, tat, pct)

transform(datf, max_plus = 
            ave(pct, tat, FUN = function(x) max(x) + seq_along(x) - 1))
#R>    dat tat pct max_plus
#R> 1    A ttt  14       14
#R> 2    B ttt   7       15
#R> 3    C ttt  12       16
#R> 4    A ttt   8       17
#R> 5    B ttt  11       18
#R> 6    C ttt  13       19
#R> 7    A aaa  19       20
#R> 8    B aaa   6       21
#R> 9    C aaa   9       22
#R> 10   A aaa  11       23
#R> 11   B aaa  13       24
#R> 12   C aaa  20       25
#R> 13   A ddd  11       18
#R> 14   B ddd  18       19
#R> 15   C ddd   6       20
#R> 16   A ddd   9       21
#R> 17   B ddd  10       22
#R> 18   C ddd  13       23
onyambu
1 июля 2021 в 16:21
0

transform(data, mx = max + ave(max, tat, FUN = seq) - 1) должно хватить

Benjamin Christoffersen
1 июля 2021 в 16:23
0

Вам нужно сначала вычислить max, тогда я думаю?

onyambu
1 июля 2021 в 16:26
1

хорошо в этом случае, поскольку вы используете 4.1.0, вы можете сделать data |> transform(mx = ave(pct, tat, FUN = \(x)max(x) + seq_along(x) - 1)) или просто transform(data, mx = ave(pct, tat, FUN = \(x)max(x) + seq_along(x) - 1))

Benjamin Christoffersen
1 июля 2021 в 16:28
0

Гораздо лучший ответ. Я должен использовать ave больше для других вещей, чем средние значения.