Возвращаемое значение в столбце 1, если значение в столбце 2 превышает 2 в первый раз - PullRequest
0 голосов
/ 14 сентября 2018

У меня есть фрейм данных с именем "new_dat", содержащий время (дни) в столбце t и данные о температуре (и иногда NA) в столбцах A - C (см. Пример в приведенном ниже коде):

> new_dat
     t    A    B    C
1  0.00 0.82 0.88 0.46
2  0.01 0.87 0.94 0.52
3  0.02   NA   NA   NA
4  0.03 0.95 1.03 0.62
5  0.04 0.98 1.06 0.67
6  0.05 1.01 1.09 0.71
7  0.06 2.00 1.13 2.00
8  0.07 1.06 1.16 0.78
9  0.08 1.07 1.18 0.81
10 0.09 1.09 1.20 0.84
11 0.10 1.10 1.21 0.86
12 0.11 2.00 1.22 0.87

Вот dput () кадра данных:

structure(list(t = c(0, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 
0.08, 0.09, 0.1, 0.11), A = c(0.82, 0.870000000000001, NA, 
0.949999999999999, 
0.979999999999997, 1.01, 2, 1.06, 1.07, 1.09, 1.1, 2), B = 
c(0.879999999999999, 
0.940000000000001, NA, 1.03, 1.06, 1.09, 1.13, 1.16, 1.18, 1.2, 
1.21, 1.22), C = c(0.460000000000001, 0.520000000000003, NA, 
0.619999999999997, 0.669999999999998, 0.709999999999997, 2, 
0.780000000000001, 
0.809999999999999, 0.84, 0.859999999999999, 0.87)), .Names = c("t", 
"A", "B", "C"), row.names = c(NA, 12L), class = "data.frame")

В качестве вывода я хочу вектор (список?) Значений столбца t, где показание температуры из столбцов AC> = 2в первый раз (и только в первый раз), или - если температура никогда не> = 2 - вернуть последнее значение времени в столбце t (0.11 в моем примере).Таким образом, «A» будет возвращать значение 0,06 (а не 0,11), «B» будет иметь значение 0,11, а «C» 0,06.Я намеревался использовать вектор, сгенерированный для создания нового фрейма данных примерно так:

      A    B    C
    0.06 0.11 0.06

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

#create blank vector to add my results to
aer <- c()

#loop by column, then by row, adding values according to the if statement
for (c in 2:ncol(new_dat)){
  c <- c
  for (r in 1:nrow(new_dat)){
    r <- r
    if ((!is.na(new_dat[r,c] )) & (new_dat[r,c] >= 2)){
      aer <- c(aer, new_dat$t[r])
    }
  }
}

Возвращает мой вектор aer, как:

> aer
[1] 0.06 0.11 0.06

Таким образом, он возвращает оба экземпляра, в которых «A» равен 2, и один из столбца «C».

Я не знаю, как дать указание циклу остановиться и перейти к следующему столбцу после нахожденияодин случай, когда мое утверждение «если» верно.Я также попытался добавить «else», чтобы охватить ситуацию, когда температура не превышает 2:

else {
  aer <- c(aer, new_dat$t[nrow(new_dat)])

Но это не сработало.

Буду признателен за любую помощь в заполнении кода, илипредложения для лучшего решения.

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018
library(tidyverse)

new_dat %>%
  gather(col, temp, -t) %>%   # reshape data
  na.omit() %>%               # remove rows with NAs
  group_by(col) %>%           # for each column value
  summarise(v = ifelse(is.na(first(t[temp >= 2])), last(t), first(t[temp >= 2]))) %>%  # return the last t value if there are no temp >=2 otherwise return the first t with temp >= 2
  spread(col, v)              # reshape again

# # A tibble: 1 x 3
#      A     B     C
#     <dbl> <dbl> <dbl>
#   1  0.06  0.11  0.06

Это решение автоматически создаст для вас фрейм данных вместо того, чтобы возвращать вектор для создания фрейма данных самостоятельно.

0 голосов
/ 14 сентября 2018

Вот решение с двумя шагами.
Сначала получите индексный вектор значений, которые вы хотите, а затем используйте этот индексный вектор для подмножества кадра данных.

inx <- sapply(new_dat[-1], function(x) {
  w <- which(x >= 2)
  if(length(w)) min(w) else NROW(x)
})
new_dat[inx, 1]
#[1] 0.06 0.11 0.06
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...