использование нескольких фреймов данных и справочной таблицы для выполнения функций в - PullRequest
0 голосов
/ 12 февраля 2019

Я новичок в r и у меня сложный набор данных, поэтому надеюсь, что мои объяснения верны.У меня есть несколько фреймов данных, которые мне нужно использовать для выполнения ряда вещей.Вот один пример.У меня есть три кадра данных.Один из них представляет собой список названий видов и соответствующих кодов:

>df.sp
    Species Code
    Picea   PI
    Pinus   CA

Другой представляет собой список сайтов с данными о численности видов для различных мест (dir).К сожалению, порядок видов различен.

>df.site
Site  dir total  t01 t02 t03 t04
2         Total   PI  CA  AB  T
2     N    9      1   5   na na
2                 AB  ZI PI CA
2     S    5     2   2  1  4
3                 DD  EE AB YT
3     N    6     1   1  5   3
3                 AB YT  EE  DD
3     S     5     4   3  1   1

Тогда у меня также есть фрейм данных черт, соответствующих виду:

>df.trait
Species  leaft  rootl
Picea     0.01    1.2
Pinus     0.02    3.5

Пример одной вещи, которую я хочу сделать, - получить среднее значение для каждой черты (df.trait $ leaft и df.trait $ rootl) для всех видов на сайте (сайт df.site $) и на сайте (df.site $ сайт N, S).Таким образом, результат будет для первого ряда:

Site dir leaft rootl
2    N   0.015  2.35

Надеюсь, это имеет смысл.Мне очень сложно продумать, как это сделать.Я пытался работать с этого поста и с этого (и многих других), но заблудился.Спасибо за помощь.Очень признателен.

ОБНОВЛЕНИЕ: Вот пример фактического df.site (уменьшенный) с использованием dput:

> dput(head(df.site))
structure(list(Site = c(2L, 2L, 2L, 2L, 2L, 2L), dir = c("rep17316", 
"N", "", "S", "", "SE"), total = c("Total", "9", "", 
"10", "", "9"), t01 = c("PI", "4", "CA", "1", "SILLAC", 
"3"), t02 = c("CXBLAN", "3", "ZIZAUR", "4", "OENPIL", "2"), 
    t03 = c("ZIZAPT", "1", "ECHPUR", "2", "ASCSYR", "2")), .Names = c("site", "dir", "total", "t01", "t02", "t03"), row.names = 2:7, class = "data.frame")

1 Ответ

0 голосов
/ 12 февраля 2019

Тебе придется сначала свернуть свои данные в гораздо более чистую форму.Я предполагаю, что структура, которую вы dput выше, согласована на всем вашем df.site фрейме данных;а именно, что строки являются парными, первая из которых указывает код вида, вторая из которых имеет счетчик (или некоторые другие собранные данные?).

Начиная с df в качестве кадра данных, который вы dput()выше, я сначала смоделирую некоторые данные для двух других фреймов:

df.sp <- data.frame(Species = paste0("species",1:8),
                    Code = c("ECHPUR", "CXBLAN", "ZIZAPT",
                             "CAMROT", "SILLAC", "OENPIL",
                             "ASCSYR", "ZIZAUR"))
df.sp
#>    Species   Code
#> 1 species1 ECHPUR
#> 2 species2 CXBLAN
#> 3 species3 ZIZAPT
#> 4 species4 CAMROT
#> 5 species5 SILLAC
#> 6 species6 OENPIL
#> 7 species7 ASCSYR
#> 8 species8 ZIZAUR

df.trait <- data.frame(Species = paste0("species",1:8),
                       leaft = round(runif(8, max=.2), 2),
                       rootl = round(runif(8, min=1, max=4),1))

df.trait
#>    Species leaft rootl
#> 1 species1  0.12   2.5
#> 2 species2  0.04   2.6
#> 3 species3  0.12   2.1
#> 4 species4  0.05   1.1
#> 5 species5  0.15   2.5
#> 6 species6  0.15   3.3
#> 7 species7  0.05   3.9
#> 8 species8  0.13   2.1

Во-первых, давайте очистим df, переместив эти вторые строки, содержащие собранные данные, и переместив эти значения в новый наборстолбцы:

library(dplyr)

df.clean <- df %>% 
  #for each row, copy the direction and total from the following row
  mutate_at(vars(matches("dir|total")), lead) %>% 
  #create new columns for observed data and fill in values from following row
  mutate_at(vars(matches("t\\d+$")), 
            .funs = funs(n = lead(.))) %>% 
  #filter to rows with species code in t01
  filter(t01 %in% df.sp$Code) %>% 
  #drop "total" column (doesn't make sense after reshape)
  select(-total)

df.clean
#>   site dir    t01    t02    t03 t01_n t02_n t03_n
#> 1    2   N ECHPUR CXBLAN ZIZAPT     4     3     1
#> 2    2   S CAMROT ZIZAUR ECHPUR     1     4     2
#> 3    2  SE SILLAC OENPIL ASCSYR     3     2     2

Теперь у нас есть два набора соответствующих столбцов, которые имеют коды видов и значения соответственно.Чтобы преобразовать датафрейм в длинную форму, мы будем использовать melt() из пакета data.table.См. Ответы на на этот вопрос , чтобы найти другие примеры того, как это сделать.

library(data.table)

df.clean <- df.clean %>% 
  setDT() %>% #convert to data.table to use data.tabel::melt
  melt(measure.vars = patterns("t\\d+$", "_n$"),
       value.name = c("Code", "Count") ) %>% 
  #drop "variable" column, which isn't needed
  select(-variable)

Наконец, объедините три кадра данных:

#merge tables together
df.summaries <- df.clean %>% 
  left_join(df.sp) %>% 
  left_join(df.trait)

На этом этапе выдолжны иметь возможность суммировать ваши данные по любым интересующим вас группам, используя group_by и summarise.

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