для каждой строки во фрейме данных выведите имя столбца, который содержит значение, меньшее или равное x, и рассчитывает оставшееся значение до следующего наибольшего значения - PullRequest
0 голосов
/ 16 марта 2020

Я ищу способ вернуть имя первого столбца, которое больше или равно x, но меньше, чем следующее наибольшее значение в каждой строке фрейма данных в новом столбце

> df <- data.frame(Loc = c("3120", "3120", "3120"), fld = c("T1", "T2", "T3"), days = c(13, 11, 18), VE = c(10,10,10), VC = c(15,15,15), V1 = c(20,20,20)
+ )
> df
   Loc fld days VE VC V1
1 3120  T1   13 10 15 20
2 3120  T2   11 10 15 20
3 3120  T3   18 10 15 20

основываясь на Lo c и fld, я хочу взять значения дней и найти ближайшее значение в VE: V1 и распечатать имя столбца этого ближайшего значения в новом столбце, а затем вычислить оставшееся до следующего наибольшего значения.

  Loc fld days VE VC V1 current.growth.stage days.to.next.stage
1 3120  T1   13 10 15 20                   VE                  2
2 3120  T2   11 10 15 20                   VE                  4
3 3120  T3   18 10 15 20                   VC                  2

Я видел несколько потоков по использованию значений min и max, но не список значений из столбца, выбранного в df для справки. любая помощь будет оценена!

спасибо.

ML

Ответы [ 2 ]

0 голосов
/ 16 марта 2020

С tidyverse вы можете сделать:

library(tidyverse)

df %>%
  pivot_longer(cols = c(VE, VC, V1), names_to = "stage", values_to = "stage_val") %>%
  group_by(Loc, fld) %>%
  mutate(current.growth.stage = stage[findInterval(days, stage_val)],
         next.stage = stage[findInterval(days, stage_val) + 1],
         days.to.next.stage = stage_val[stage == next.stage] - days) %>%
  filter(stage == current.growth.stage) %>%
  select(-c(stage, next.stage, stage_val)) %>%
  right_join(df)

Выход

# A tibble: 3 x 8
# Groups:   Loc, fld [3]
  Loc   fld    days current.growth.stage days.to.next.stage    VE    VC    V1
  <fct> <fct> <dbl> <chr>                             <dbl> <dbl> <dbl> <dbl>
1 3120  T1       13 VE                                    2    10    15    20
2 3120  T2       11 VE                                    4    10    15    20
3 3120  T3       18 VC                                    2    10    15    20
0 голосов
/ 16 марта 2020

Вы можете использовать apply с необходимыми столбцами, например так:

df$current <- apply(df[3:6], 1, function(x) names(df)[3 + which.max(which(x[2:4] < x[1]))])
df$next_stage <- apply(df[3:6], 1, function(x) (x[2:4] - x[1])[x[2:4] - x[1] > 0][1])
df
#>    Loc fld days VE VC V1 current next_stage
#> 1 3120  T1   13 10 15 20      VE          2
#> 2 3120  T2   11 10 15 20      VE          4
#> 3 3120  T3   18 10 15 20      VC          2

Создано в 2020-03-16 пакетом Представить (v0.3.0)

...