Подмножество фрейма данных в зависимости от того, больше или меньше значение в столбце ссылок 0 - PullRequest
3 голосов
/ 28 марта 2019

Мне нужно установить набор данных на основе столбца эталонных значений.Например, учитывая набор данных:

col1 <- c(1,2,3,4)
col2 <- c(1,2,-1,4)
col3 <- c(1,2,-3,-4)
col_Reference <- c(-5,6,-7,8)
df <- cbind(col1,col2,col3,col_Reference)
df
     col1 col2 col3 col_Reference
[1,]    1    1    1            -5
[2,]    2    2    2             6
[3,]    3   -1   -3            -7
[4,]    4    4   -4             8

Я хотел бы отфильтровать эти строки в зависимости от значения в col_Reference.Если значение больше 0, я хочу сохранить строку, только если каждое значение также больше 0. Вместо этого, если значение меньше 0, я хочу сохранить строку только, если каждое значение также меньше 0. Допустимое значение 0несоответствие Я хотел бы получить обратно:

     col1 col2 col3 col_Reference
[1,]    2    2    2             6

Тогда я также хотел бы контролировать, сколько разрешено несоответствие: Разрешение на макс. 1 несоответствие я должен иметь обратно:

     col1 col2 col3 col_Reference
[1,]    2    2    2             6
[2,]    3   -1   -3            -7

разрешениепри максимуме 2:

     col1 col2 col3 col_Reference
[1,]    2    2    2             6
[2,]    3   -1   -3            -7
[3,]    4    4   -4             8

Полагаю, мне следует использовать apply(), но я должен признать, что я не очень хорош в его использовании: (

Большое спасибо

Ответы [ 4 ]

3 голосов
/ 28 марта 2019

Не самое элегантное решение, но оно делает свое дело!

#Create the testing dataframe
col1 <- c(1,2,3,4)
col2 <- c(1,2,-1,4)
col3 <- c(1,2,-3,-4)
col_Reference <- c(-5,6,-7,8)
df <- cbind(col1,col2,col3,col_Reference)

#Create the function to do what we want
fun <- function(df, mismatch = 0){
  df <- as.data.frame(df)
  df <- apply(df, 1, function(r){
    if(sum(sign(r[1:(ncol(df)-1)]) != sign(r['col_Reference'])) <= mismatch){
      return(r)
    }else{
      return(NULL)
    }
  })
  df <- do.call('rbind', df)
  return(df)
}

Теперь вызовите функцию!

fun(df)

        col1 col2 col3 col_Reference
[1,]    2    2    2             6

fun(df, mismatch = 1)

        col1 col2 col3 col_Reference
[1,]    2    2    2             6
[2,]    3   -1   -3            -7
[3,]    4    4   -4             8

fun(df, mismatch = 2)

        col1 col2 col3 col_Reference
[1,]    2    2    2             6
[2,]    3   -1   -3            -7
[3,]    4    4   -4             8

3 голосов
/ 28 марта 2019

Для первого

df[apply(df, 1, function(x) all(sign(x) == sign(tail(x, 1)))), , drop = FALSE]
#     col1 col2 col3 col_Reference
#[1,]    2    2    2             6

Разрешение n несоответствие

n = 1
df[apply(df, 1, function(x) sum(!(sign(head(x, -1)) == sign(tail(x, 1))))) <= n, , drop = FALSE]
#     col1 col2 col3 col_Reference
#[1,]    2    2    2             6
#[2,]    3   -1   -3            -7
#[3,]    4    4   -4             8
2 голосов
/ 28 марта 2019

Это должно работать:

# All 3 must have the same sign at the reference
df[apply(df, 1, function(x)sum(sign(x[4])*sign(x[1:3]) > 0) == 3),]
# At least 2 must have the same sign as the reference
df[apply(df, 1, function(x)sum(sign(x[4])*sign(x[1:3]) > 0) >= 2),]

Проверка того, сколько значений в первых 3 столбцах имеют тот же знак, что и значение в контрольном столбце.

1 голос
/ 29 марта 2019

Это также можно сделать с помощью этого краткого кода, используя rowSums() и sign()

mismatch = 1
df[rowSums(sign(df)) >= (ncol(df) - mismatch * 2), ]

     col1 col2 col3 col_Reference
[1,]    1    1    1            -5
[2,]    2    2    2             6
[3,]    4    4   -4             8
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...