Сравните одну переменную с другими переменными по группе в R - PullRequest
0 голосов
/ 04 марта 2019

У меня есть следующий фрейм данных:

data.frame(id = c("a", "a", "a", "d", "d"),
           value = c(5, 46, 12, 14, 32),
           low = c(46, 8, NA, 0, 34),
           high = c(56, 20, NA, 12, 60))

  id value low high
1  a     5  46   56
2  a    46   8   20
3  a    12  NA   NA
4  d    14   0   12
5  d    32  34   60

Мне нужно установить новую переменную на TRUE, если value выходит за пределы каждого интервала, определенного low и high для каждогострока с таким же id.

Мой желаемый фрейм данных будет:

   id value low high result
1   a     5  45   56   TRUE    # 5 not in 45-56, 8-20
2   a    46   8   20  FALSE    # 46 in 45-56
3   a    12  NA   NA  FALSE    # 12 in 8-20
4   d    14   0   12   TRUE    # 14 not in 0-12, 34-60 
5   d    32  34   60   TRUE    # 32 not in 0-12, 34-60

Как я могу сделать это в базе R?Я работаю в ограничительной среде, где у меня есть доступ только к базе R.

Ответы [ 3 ]

0 голосов
/ 04 марта 2019

Без apply, sapply и map функции:

isInDataframe <- function(data = data, value = "value", from = "low", to = "high", id = "id"){
    result <- c()
    for (i in 1:length(data[,1])) {
      deeta <- data[data[id] == as.character(data[id][i,1]),]
      subresult <- c()
      for (j in 1:nrow(deeta)) {
        subresult[j] <- (data[value][i,1] >= deeta[from][j,1] & data[value][i,1] <= deeta[to][j,1])
  }
      result[i] <- !any(subresult,na.rm = T) 
    }
    data$result <- result
    return(data)
}

isInDataframe(data = data, value = "value", from = "low", to = "high", id = "id")
id value low high result
1  a     5  46   56   TRUE
2  a    46   8   20  FALSE
3  a    12  NA   NA  FALSE
4  d    14   0   12   TRUE
5  d    32  34   60   TRUE
0 голосов
/ 07 апреля 2019

Я, наконец, решил разделить id и value во фрейме данных и id, low и high в другом фрейме данных для этого анализа.

Однако здесьрешение, вдохновленное решениями, предложенными для этого нового подхода :

df <- data.frame(id = c("a", "a", "a", "d", "d"),
                 value = c(5, 46, 12, 14, 32),
                 low = c(46, 8, NA, 0, 34),
                 high = c(56, 20, NA, 12, 60))

temp <- merge(x = df[c("id",
                       "value")],
              y = df[c("id",
                       "low",
                       "high")])

temp$result <- temp$value < temp$low | temp$value > temp$high

merge(x = df,
      y = aggregate(formula = result ~ id + value,
                    data = temp,
                    FUN = all))

  id value low high result
1  a    12  NA   NA  FALSE
2  a    46   8   20  FALSE
3  a     5  46   56   TRUE
4  d    14   0   12   TRUE
5  d    32  34   60   TRUE
0 голосов
/ 04 марта 2019

Я разобрался с некрасивым и неоптимизированным решением, но оно работает!Вот код:

df <- data.frame(id = c("a", "a", "a", "d", "d"),
       value = c(5, 46, 12, 14, 32),
       low = c(46, 8, NA, 0, 34),
       high = c(56, 20, NA, 12, 60))

list.inter <- list()

for(i in 1:nrow(df)){
 if(is.na(df$low[i]) | is.na(df$low[i])) {
   list.inter[[i]] <- NA
 }else{
   list.inter[[i]] <- seq(from = df$low[i], to = df$high[i])
 }
}

result <- c()
for(i in 1:nrow(df)){
  result[i] <-  ! df$value[i] %in% unlist(list.inter[which(df$id[i]==df$id)])
}

df$result <- result

Надеюсь, это поможет, и мне любопытно увидеть оптимизированный код от других пользователей!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...