R извлечь значение из столбца и строки во фрейме данных

#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