Как запустить циклы for для частей фрейма данных в то время? - PullRequest
1 голос
/ 28 января 2020

R newb ie здесь! У меня есть фрейм данных, где есть несколько измерений для одного и того же идентификатора. Вот упрощенный пример этого.

id<-c(1,1,1,2,2,2,3,3,3)
x<-as.numeric(c(1:9))
y<-c(2,4,1,5,7,3,9,6,8)
z<-rep("text",9)
cal<-0
df<- data.frame(id, x, y,z,cal)

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

for (j in 2:length(df$x))
  {if (df$x[j]>=df$y[j]) {df$cal[j]<-df$x[j]+df$y[j-1]
  }else{
     df$cal[j]<- df$x[j]-df$y[j-1]
    }
  }

Так что в основном я хотел бы, чтобы l oop работал через первый идентификатор, прежде чем перейти ко второму, а затем к третьему и так далее. Ожидаемым результатом будет следующий фрейм данных (0 - это совпадение):

> df
  id x y    z cal
1  1 1 2 text   0
2  1 2 4 text   0
3  1 3 1 text   7
-----------------
4  2 4 5 text   0
5  2 5 7 text   0
6  2 6 3 text   13
-----------------
7  3 7 9 text   0
8  3 8 6 text   17
9  3 9 8 text   15

Поскольку я не хотел создавать подмножество фреймов данных для каждого идентификатора, я попытался использовать for-l oop также для идентификаторов.

for (i in 1:3)
{if (df$id==i) {
  for (j in 2:length(df$x))
  {if (df$x[j]>=df$y[j]) {df$cal[j]<-df$x[j]+df$y[j-1]
  }else{
     df$cal[j]<- df$x[j]-df$y[j-1]
    }
  }
}
} 

Однако это дало следующее предупреждение: 1: In if (df$id == i) { : the condition has length > 1 and only the first element will be used

Итак, теперь я знаю, что это потому, что я пытаюсь сравнить вектор в другой вектор, который должен дать «ИСТИНА» или «ЛОЖЬ». Однако сравнение идентификаторов разных строк также не помогает, потому что тогда мне нужно всегда вручную изменять значение идентификатора, например, for (i in 1:length(which(df$id==1))).

Я пытался найти другие способы, как это сделать, но не нашел ответа. Любая помощь будет принята с благодарностью!

1 Ответ

1 голос
/ 28 января 2020
library(tidyverse) # this loads several packages that will help you.

df %>% # now you take your df
    mutate(cal = if_else(x >= y # and calculate the column cal
                         , x + lag(y) # if x >= y then calculate this
                         , x - lag(y))) # else calculate this

  id x y    z cal
1  1 1 2 text  NA
2  1 2 4 text   0
3  1 3 1 text   7
4  2 4 5 text   3
5  2 5 7 text   0
6  2 6 3 text  13
7  3 7 9 text   4
8  3 8 6 text  17
9  3 9 8 text  15

Вам не нужен l oop. R векторизован. lag() создает вектор, который "сдвинут" на один элемент.

Непонятно, о чем вторая часть вопроса, но может ли быть, что вы ищете это?

df %>%
    group_by(id) %>%
    mutate(cal = if_else(x >= y
                         , x + lag(y)
                         , x - lag(y)))

    id     x     y z       cal
<dbl> <dbl> <dbl> <fct> <dbl>
    1     1     1     2 text     NA
    2     1     2     4 text      0
    3     1     3     1 text      7
    4     2     4     5 text     NA
    5     2     5     7 text      0
    6     2     6     3 text     13
    7     3     7     9 text     NA
    8     3     8     6 text     17
    9     3     9     8 text     15
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...