#r #dataframe #data-extraction
#r #фрейм данных #извлечение данных
Вопрос:
У меня есть фрейм данных, подобный этому
#dt
# one two row MAX_row three four
#1: a 1 0 2 yes yes
#2: a 2 2 2 yes yes
#3: a 3 0 2 no yes
#4: b 1 0 5 yes no
#5: b 2 5 5 no no
#6: b 3 0 5 no no
для создания переменных row и MAX_row я создал следующий код:
dt$row <-ifelse(dt$two == 2,rownames(dt), 0)
dt <- dt %>% group_by(one) %>% mutate(MAX_row=max(row))
и то, что я пытаюсь сейчас сделать, это заполнить четвертый столбец значениями из строки в третьем столбце. Номера строк указаны в столбце MAX_row. Итак, в четвертом столбце для строки с ‘a’ в первом столбце должны быть значения из строки номер 2 в третьем столбце, как я показал в dt.
Я думал, что следующий код будет в порядке, но он выдает нечетные значения:
dt$four <- ifelse(dt$one=='a',dt$three[dt$MAX_row],0)
Есть идеи?
Комментарии:
1. Почему вы смешиваете
data.table
иdplyr
синтаксис? Лучше всего оставаться в рамках одной структуры.2. Кроме того,
row
это тоже функция, поэтому было бы лучше, если бы вы вызывали свою переменную с другим именем
Ответ №1:
Если я правильно понимаю, вы начинаете с трех столбцов one
, two
и three
и я думаю, что row
и MAX_row
являются временными переменными, созданными для достижения till four
.
Мы можем получить ожидаемый результат без необходимости создавать эти переменные.
library(dplyr)
df %>%
group_by(one) %>%
mutate(four = three[which.max(two == 2)])
# one two three four
# <fct> <int> <fct> <fct>
#1 a 1 yes yes
#2 a 2 yes yes
#3 a 3 no yes
#4 b 1 yes no
#5 b 2 no no
#6 b 3 no no
Это по-прежнему дает ожидаемый результат без создания row
и MAX_row
.
данные
df <- structure(list(one = structure(c(1L, 1L, 1L, 2L, 2L, 2L), .Label
= c("a",
"b"), class = "factor"), two = c(1L, 2L, 3L, 1L, 2L, 3L), three =
structure(c(2L,
2L, 1L, 2L, 1L, 1L), .Label = c("no", "yes"), class = "factor")),
row.names = c("1:",
"2:", "3:", "4:", "5:", "6:"), class = "data.frame")
Ответ №2:
Лучше не смешивать data.table
и dplyr
синтаксис. Поскольку dt
кажется, что data.table
вот data.table
решение
dt[
, row := ifelse(two == 2, .I, 0)][,
, MAX_row := max(row), by = one][,
, four := ifelse(one == "a", three[MAX_row], 0)]
# one two row MAX_row three four
#1: a 1 0 2 yes yes
#2: a 2 2 2 yes yes
#3: a 3 0 2 no yes
#4: b 1 0 5 yes no
#5: b 2 5 5 no no
#6: b 3 0 5 no no
Или все за один шаг, избегая генерации row
и MAX_row
(как выделено Ronak)
dt[, four := three[which.max(two == 2)], by = one]
# one two row MAX_row three four
#1: a 1 0 2 yes yes
#2: a 2 2 2 yes yes
#3: a 3 0 2 no yes
#4: b 1 0 5 yes no
#5: b 2 5 5 no no
#6: b 3 0 5 no no