Привет всем, я надеюсь, что вы, ребята, отлично проводите неделю.
У меня есть небольшой набор данных из 4 переменных: одна — subject
, вторая — key
, которая представляет собой код, который субъект использует для входа в систему, третья — order
, которая будет отслеживать хронологический год, и, наконец, переменная Period
, которая указывает, был ли ключ использовано в предыдущий раз past
или в текущем месяце current
.
Это набор данных:
subjects<-c(rep("James",3),
rep("Alex",2),
rep("Mila",8),
rep("Mark",1))
keys<-c(rep("IX08-8",2),"IX08-8",
"UX-007","HH-011",rep("PO_85",7),"UJ_8","785_PO")
order<-c(1:14)
period<-c("past","past","current","past","current",rep("past",6),"current","current","current")
df<-cbind(subjects,keys,period,order)
> head(df)
subjects keys period order
[1,] "James" "IX08-8" "past" "1"
[2,] "James" "IX08-8" "past" "2"
[3,] "James" "IX08-8" "current" "3"
[4,] "Alex" "UX-007" "past" "4"
[5,] "Alex" "HH-011" "current" "5"
[6,] "Mila" "PO_85" "past" "6"
в конечном счете, я должен быть в состоянии сказать, использует ли субъект ранее использовавшийся key
для входа в систему в current
Период, если subject
использует новый key
для входа в систему в текущем period
, тогда я присвою значение " 1» в столбец с именем result
, если пользователь не использовал ранее использовавшийся key
для входа в систему во время текущего period
, присвоенное значение должно быть «0», а в противном случае — «Н/П».
Мой желаемый результат будет выглядеть так:
subjects keys period order result
[1,] "James" "IX08-8" "past" "1" NA
[2,] "James" "IX08-8" "past" "2" NA
[3,] "James" "IX08-8" "current" "3" "0"
[4,] "Alex" "UX-007" "past" "4" NA
[5,] "Alex" "HH-011" "current" "5" "1"
[6,] "Mila" "PO_85" "past" "6" NA
[7,] "Mila" "PO_85" "past" "7" NA
[8,] "Mila" "PO_85" "past" "8" NA
[9,] "Mila" "PO_85" "past" "9" NA
[10,] "Mila" "PO_85" "past" "10" NA
[11,] "Mila" "PO_85" "past" "11" NA
[12,] "Mila" "PO_85" "current" "12" "0"
[13,] "Mila" "UJ_8" "current" "13" "1"
[14,] "Mark" "785_PO" "current" "14" "1"
Например, в строке № 3 Джеймс присвоил результату значение 0, потому что он использовал ранее использовавшийся ключ для входа в систему в текущем месяце, который был ключом «IX08-8», но Марк имеет значение 1 в строке. столбец результатов, потому что система отследила только один ключ, и это ключ, который он использовал для входа в этот текущий период, который технически является «новым ключом».
Что я сделал, чтобы решить эту проблему?
Я могу сгруппировать набор данных по subject
и убедиться, что он расположен по order
по убыванию, но я могу думать только о создании вектора ключей (vector.of.previous.keys
) для каждого субъекта на основе (period = "past"
), а затем оценить, является ли текущий ключ %in%
vector.of.previous.keys
, но если бы был способ проверки только внутри групп по этому критерию, это было бы намного эффективнее. Большое спасибо, ребята, за вашу помощь.
Предполагая, что ваши данные хранятся в data.frame
df <- data.frame(subjects,keys,period,order)
вы могли бы использовать
library(dplyr)
df %>%
group_by(subjects, keys) %>%
mutate(count = row_number()) %>%
group_by(subjects) %>%
mutate(result = case_when(period == "current" & count == 1 ~ 1,
period == "current" & count >= 1 ~ 0,
TRUE ~ NA_real_)) %>%
ungroup() %>%
select(-count)
получить
# A tibble: 14 x 5
subjects keys period order result
<chr> <chr> <chr> <int> <dbl>
1 James IX08-8 past 1 NA
2 James IX08-8 past 2 NA
3 James IX08-8 current 3 0
4 Alex UX-007 past 4 NA
5 Alex HH-011 current 5 1
6 Mila PO_85 past 6 NA
7 Mila PO_85 past 7 NA
8 Mila PO_85 past 8 NA
9 Mila PO_85 past 9 NA
10 Mila PO_85 past 10 NA
11 Mila PO_85 past 11 NA
12 Mila PO_85 current 12 0
13 Mila UJ_8 current 13 1
14 Mark 785_PO current 14 1
Еще один метод dplyr
здесь, где все ваши условия закодированы в операторе case_when
.
library(dplyr)
df %>%
group_by(subjects) %>%
mutate(result = case_when(period == "current" & n() == 1 ~ "1",
period == "current" & keys == first(keys) ~ "0",
period == "current" & keys != first(keys) & n() > 1 ~ "1",
period == "past" ~ NA_character_,
TRUE == "past" ~ NA_character_))
# A tibble: 14 × 5
# Groups: subjects [4]
subjects keys period order result
<chr> <chr> <chr> <int> <chr>
1 James IX08-8 past 1 NA
2 James IX08-8 past 2 NA
3 James IX08-8 current 3 0
4 Alex UX-007 past 4 NA
5 Alex HH-011 current 5 1
6 Mila PO_85 past 6 NA
7 Mila PO_85 past 7 NA
8 Mila PO_85 past 8 NA
9 Mila PO_85 past 9 NA
10 Mila PO_85 past 10 NA
11 Mila PO_85 past 11 NA
12 Mila PO_85 current 12 0
13 Mila UJ_8 current 13 1
14 Mark 785_PO current 14 1
Обратите внимание, что я изменил ваш cbind()
на data.frame
(с фреймом данных легче работать по сравнению с матрицей).
subjects<-c(rep("James",3),
rep("Alex",2),
rep("Mila",8),
rep("Mark",1))
keys<-c(rep("IX08-8",2),"IX08-8",
"UX-007","HH-011",rep("PO_85",7),"UJ_8","785_PO")
order<-c(1:14)
period<-c("past","past","current","past","current",rep("past",6),"current","current","current")
df<-data.frame(subjects,keys,period,order)
@R_Student Да, ты прав. Подробнее здесь
Эй, @benson23, спасибо за быстрый ответ, вы очень талантливы, не могли бы вы сообщить мне, будет ли использование «first» просто сравнением самого первого элемента группы с текущим? Спасибо большое