r преобразовать сводные данные в данные о присутствии / отсутствии - PullRequest
1 голос
/ 11 июля 2020

Я провел 5 измерений присутствия / отсутствия на нескольких сайтах, суммировал их вместе и получил фрейм данных, который выглядел примерно так:

df <- data.frame("site" = c("a", "b", "c"), 
                 "species1" = c(0, 2, 1), 
                 "species2" = c(5, 2, 4))

ie. на участке "a" разновидность 1 была зарегистрирована 0/5 раз, а разновидность 2 была зарегистрирована 5/5 раз.

Я хотел бы преобразовать это обратно в данные о присутствии / отсутствии. Примерно так:

data.frame("site" = ("a", "b", "c"), 
           "species1" = c(0,0,0,0,0, 1,1,0,0,0, 1,0,0,0,0),
           "species2" = c(1,1,1,1,1, 1,1,0,0,0, 1,1,1,1,0))

Я могу продублировать каждую строку 5 раз с:

df %>% slice(rep(1:n(), each = 5))

, но я не могу понять, как заменить «2» на «1,1, 0,0,0 ". В идеале порядок единиц и нулей (внутри каждого сайта) также должен быть случайным (ie. «0,0,1,0,1»), но это может быть слишком сложно.

Любая помощь были бы признательны.

Ответы [ 2 ]

1 голос
/ 11 июля 2020

Мы также можем использовать uncount

library(dplyr)
library(tidyr)
df %>% 
   uncount(max(species2), .remove = FALSE) %>% 
   group_by(site) %>%
   mutate(across(starts_with('species'), ~ as.integer(row_number() <= first(.))))
# A tibble: 15 x 3
# Groups:   site [3]
#   site  species1 species2
#   <chr>    <int>    <int>
# 1 a            0        1
# 2 a            0        1
# 3 a            0        1
# 4 a            0        1
# 5 a            0        1
# 6 b            1        1
# 7 b            1        1
# 8 b            0        0
# 9 b            0        0
#10 b            0        0
#11 c            1        1
#12 c            0        1
#13 c            0        1
#14 c            0        1
#15 c            0        0
1 голос
/ 11 июля 2020

После повторения строк вы можете сравнить номер строки с любым значением соответствующего столбца и присвоить 1, если текущий номер строки меньше значения.

library(dplyr)

df %>% 
  slice(rep(seq_len(n()), each = 5)) %>%
  group_by(site) %>%
  mutate(across(starts_with('species'), ~+(row_number() <= first(.))))
  #Use mutate_at with old dplyr
  #mutate_at(vars(starts_with('species')), ~+(row_number() <= first(.)))


#   site  species1 species2
#   <chr>    <int>    <int>
# 1 a            0        1
# 2 a            0        1
# 3 a            0        1
# 4 a            0        1
# 5 a            0        1
# 6 b            1        1
# 7 b            1        1
# 8 b            0        0
# 9 b            0        0
#10 b            0        0
#11 c            1        1
#12 c            0        1
#13 c            0        1
#14 c            0        1
#15 c            0        0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...