Условно удалить определенные строки в R - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть очень большой фрейм данных с fi sh видами, захваченными в качестве одного из столбцов. Вот очень сокращенный пример:

ID = seq(1,50,1)

fishes = c("bass", "jack", "snapper")
common = sample(fishes, size = 50, replace = TRUE)

dat = as.data.frame(cbind(ID, common))

Я хочу удалить любые виды, которые составляют менее определенного процента данных. Например, здесь я хочу удалить все виды, которые составляют менее 30% данных:

library(dplyr)
nrow(filter(dat, common == "bass"))      #22 rows -> 22/50 -> 44%
nrow(filter(dat, common == "jack"))      #12 rows -> 12/50 -> 24%
nrow(filter(dat, common == "snapper"))   #16 rows -> 16/50 -> 32%

Здесь гнезда составляют менее 30% строк, поэтому я хочу удалить все ряды с гнездами (или все виды с менее чем 15 рядами). Это легко сделать здесь, но на самом деле у меня есть более 700 видов sh в моем фрейме данных, и я хочу выбросить все виды, которые составляют менее 1% данных (что в моем случае было бы меньше, чем 18 003 строки). Есть ли рациональный способ сделать это без необходимости отфильтровывать каждый вид отдельно?

Я представляю, возможно, что-то вроде l oop, которое говорит, что если число строк для общего имени = "x" меньше 18003, удалите эти строки ...

Ответы [ 2 ]

3 голосов
/ 27 апреля 2020

Вы также можете сделать это в одной трубе:

library(dplyr)

dat %>%
  mutate(percentage = n()) %>%
  group_by(common) %>%
  mutate(percentage = n() / percentage) %>%
  filter(percentage > 0.3) %>%
  select(-percentage)
2 голосов
/ 27 апреля 2020

Один из способов решения этой проблемы - сначала создать сводную таблицу, а затем выполнить фильтрацию на основе сводной статистики. Вероятно, есть более прямые способы сделать sh то же самое.

library(dplyr)
set.seed(914) # so you get the same results from sample()

ID = seq(1,50,1)

fishes = c("bass", "jack", "snapper")
common = sample(fishes, size = 50, replace = TRUE)

dat = as.data.frame(cbind(ID, common))  # same as your structure, but I ended up with different species mix

summ.table <-  dat %>%
      group_by(common) %>%
      summarize(number = n()) %>%
      mutate(pct= number/sum(number))
summ.table
# # A tibble: 3 x 3
# common  number   pct
# <fct>    <int> <dbl>
# 1 bass        18  0.36
# 2 jack        18  0.36
# 3 snapper     14  0.28

include <- summ.table$common[summ.table$pct > .3]

dat.selected = filter(dat, common %in% include)

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