#r
#r
Вопрос:
У меня есть следующая таблица, которая содержит факторную переменную «категория» с двумя уровнями DH1 и DH2. У меня также есть значения интервалов для факторной переменной ‘from’ и ‘to’.
category = c('DH1','DH1','DH1','DH1','DH2','DH2')
from = c(356,366,367,368,401,402)
to = c(366,367,368,369,402,403)
df <- data.frame(category,from, to)
category from to
1 DH1 365 366
2 DH1 366 367
3 DH1 367 368
4 DH1 368 369
5 DH2 401 402
6 DH2 402 403
Мне нужно создать два новых столбца, которые могут выглядеть следующим образом: как только DH1 изменяется на DH2, from1 начинается с 0 и to1 = to-from
category from to from1 to1
1 DH1 365 366 0 1
2 DH1 366 367 1 2
3 DH1 367 368 2 3
4 DH1 368 369 3 4
5 DH2 401 402 0 1
6 DH2 402 403 1 2
Я понимаю, что мне нужно иметь цикл for и перебирать ‘category’, затем иметь оператор if category[4] != category[5]
и на основе этого вычислять новые столбцы. Но есть ли более простой способ сделать это?
Комментарии:
1. Как только DH1 изменяется на DH2, значение from1 начинается с 0 и to1 = to-from.
2. … и аналогично вопросу @Ronak, для 1-й строки, как
to1
1?to - from
является366 - 356 = 10
3. @MauritsEvers Я исправил эту ошибку, приношу свои извинения за это! Это кумулятивное добавление, поскольку вторая строка to1 равна второй строке from1 1.
Ответ №1:
Существует простой способ, использующий library(dplyr)
:
df %>% arrange(category, from)
%>% group_by(category)
%>% mutate(from1 = row_number()-1, to1 = row_number())
Он сортирует данные по category
и from
и группирует по category
переменной, чтобы убедиться, что from1 и to1 могут быть основаны на номерах строк для каждой категории, используя mutate
функцию, которая используется для создания новых переменных.
Комментарии:
1. Это будет работать, но только в том случае, если интервалы всегда равны 1, но иногда они могут быть 1,5 или 2. от = 402,5 до = 404.
2. марианесс, ты никогда не показывала это в качестве примера. Все ваши входные данные показывали подсчет от 0 до n-1 или от 1 до n. Ответ @ Arnaud полностью правильный и поясняющий. Это хороший ответ. Пожалуйста, примите ответ и создайте новый вопрос с примерами, охватывающими все ваши случаи.
Ответ №2:
Возможно, вы ищете
library(dplyr)
df %>%
group_by(category) %>%
mutate(from1 = row_number() - 1,
to1 = cumsum(to - from))
# category from to from1 to1
# <fct> <dbl> <dbl> <dbl> <dbl>
#1 DH1 365 366 0 1
#2 DH1 366 367 1 2
#3 DH1 367 368 2 3
#4 DH1 368 369 3 4
#5 DH2 401 402 0 1
#6 DH2 402 403 1 2
Для каждого category
это присваивает row_number() - 1
значение from1
и вычисляет совокупную сумму to - from
значений. Если category
не упорядочен и DH1
может возникнуть снова как другая группа, нам может понадобиться group_by
data.table::rleid(category)
.
Ответ №3:
Если вы нумеруете 1 ..n внутри каждой категории, вы можете использовать пакет «dplyr»:
library(dplyr)
df %>% group_by(category) %>% mutate(to1=1:n(), from1=to1-1)
Если вы пытаетесь сравнить значение в строке i со строкой i 1, вы можете использовать функцию lag
, также из «dplyr» (встроенная lag
функция работает только с временными рядами):
dplyr::lag(df$category)
[1] <NA> DH1 DH1 DH1 DH1 DH2
Levels: DH1 DH2
(как только вы загрузите пакет «dplyr», он заменит встроенную lag
функцию, и вам не нужно вызывать ее, как я написал в примере — это было просто для того, чтобы подчеркнуть, о какой функции я говорю)