Отфильтруйте один столбец, сопоставив его с другим - PullRequest
2 голосов
/ 28 мая 2019

У меня есть фрейм данных с переменной, содержащей элементы, которые нужно удалить, если они соответствуют элементу в другой переменной - см. Небольшой пример ниже:

df <- data.frame(pair = c(1, 1, 2, 2, 3, 3),
                 animal = rep(c("dog", "cat"), 3), 
                 value = seq(1, 12, 2), 
                 drop = c("no", "no", "dog", "dog", "cat", "cat"))

  pair animal value drop
1    1    dog     1   no
2    1    cat     3   no
3    2    dog     5  dog
4    2    cat     7  dog
5    3    dog     9  cat
6    3    cat    11  cat

Я пытаюсь отфильтровать данныекадр в зависимости от того, соответствует ли значение animal значению drop.Я хочу что-то вроде filter(df, animal != drop), чтобы удалить строки, где только значение животного соответствует значению drop:

  pair animal value drop
1    1    dog     1   no
2    1    cat     3   no
4    2    cat     7  dog
5    3    dog     9  cat

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

for(i in nrow(df)){
  if(df$animal[i] == df$drop[i]){
    df <- df[-i,]
    return(df)
  }
}

Есть ли способ сделать это с помощью dplyr?

Ответы [ 2 ]

3 голосов
/ 28 мая 2019

Использование filter(df, animal != drop) правильно.Однако, поскольку вы не указали stringsAsFactors = F в своем вызове data.frame(), все строки преобразуются в коэффициенты, что повышает ошибку различных наборов уровней.Таким образом, добавление stringsAsFactors = F должно решить эту проблему

df <- data.frame(pair = c(1, 1, 2, 2, 3, 3),
                 animal = rep(c("dog", "cat"), 3), 
                 value = seq(1, 12, 2), 
                 drop = c("no", "no", "dog", "dog", "cat", "cat"),
                 stringsAsFactors = F) 

df %>%
  filter(animal != drop)

  pair animal value drop
1    1    dog     1   no
2    1    cat     3   no
3    2    cat     7  dog
4    3    dog     9  cat

Чтобы избежать проблем с этой нежелательной строкой для факторного поведения, я настоятельно рекомендую использовать tibble

В случае, если у вас нетвозможность изменить способ создания данных. Здесь я включаю решение @ akrun:

library(dplyr)

df %>% 
  mutate_at(vars(animal, drop), as.character) %>%       
  filter(animal != drop)
#  pair animal value drop
#1    1    dog     1   no
#2    1    cat     3   no
#3    2    cat     7  dog
#4    3    dog     9  cat
3 голосов
/ 28 мая 2019

Можно было бы преобразовать в character класс с mutate_at, а затем использовать filter на несоответствующих элементах

library(dplyr)
df %>% 
  mutate_at(vars(animal, drop), as.character) %>%       
  filter(animal != drop)
#  pair animal value drop
#1    1    dog     1   no
#2    1    cat     3   no
#3    2    cat     7  dog
#4    3    dog     9  cat
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...