Есть ли способ создать новые столбцы в R на основе манипуляций из нескольких фреймов данных? - PullRequest
1 голос
/ 30 марта 2020

Кто-нибудь знает, возможно ли использовать переменную в одном фрейме данных (в моем случае это «развернуть» фрейм данных) для создания переменной в другом фрейме данных?

Например, у меня есть два кадра данных:

df1:

   deploy <- data.frame(ID = c("20180101_HH1_1_1", "20180101_HH1_1_2", "20180101_HH1_1_3"), 
             Site_Depth = c(42, 93, 40), Num_Depth_Bins_Required = c(5, 100, 4), 
             Percent_Column_in_each_bin = c(20, 10, 25))

df2:

   sp.c <- data.frame(species = c("RR", "GS", "GT", "BR", "RS", "BA", "GS", "RS", "SH", "RR"), 
                      ct = c(25, 66, 1, 12, 30, 6, 1, 22, 500, 6), 
                      percent_dist_from_surf = c(11, 15, 33, 68, 71, 100, 2, 65, 5, 42))

Я хочу создать новые столбцы в df2 который присваивает каждому виду и подсчитывает в корзину на основе Percent_Column_in_each_bin для каждого идентификатора. Например, в 20180101_HH1_1_3 будет 4 корзины, каждая из которых составляет 25% столбца, а все виды, которые находятся в пределах 0-25% столбца (в df2), будут в корзине 1, а виды в пределах 25-50% от столбец будет в глубине bin 2, и так далее. Мне кажется, что это выглядит так:

    i.want.this <- data.frame(species = c("RR", "GS", "GT", "BR", "RS", "BA", "GS", "RS", "SH", "RR"), 
                      ct = c(25, 66, 1, 12, 30, 6, 1, 22, 500, 6), 
                      percent_dist_from_surf = c(11, 15, 33, 68, 71, 100, 2, 65, 5, 42),
                      '20180101_HH1_1_1_Bin' = c(1, 1, 2, 4, 4, 5, 1, 4, 1, 3),
                      '20180101_HH1_1_2_Bin' = c(2, 2, 4, 7, 8, 10, 1, 7, 1, 5), 
                      '20180101_HH1_1_3_Bin' = c(1, 1,  2, 3, 3, 4, 1, 3, 1, 2))

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

Я не знаю, возможно ли то, что я пытаюсь сделать, но я ценю обратную связь. Заранее спасибо!

Редактировать: моя конечная цель - найти максимальное количество (max ct) для каждого вида в каждой ячейке для каждого идентификатора. То, что я делал, чтобы найти это (используя корзины, сгенерированные с предложениями от @Ben), использует dplyr для нарезки и определения максимального идентификатора, например:

    20180101_HH1_1_1 <- sp.c %>%
                        group_by(20180101_HH1_1_1, species) %>%
                        arrange(desc(ct)) %>% 
                        slice(1) %>%
                        group_by(20180101_HH1_1_1) %>%
                        mutate(Count_Total_Per_Bin = sum(ct)) %>%
                        group_by(species, add=TRUE) %>% 
                        mutate(species_percent_of_total_in_bin = 
                             paste0((100*ct/Count_Total_Per_Bin) %>%
                        mutate(ID= "20180101_HH1_1_1 ") %>%
                        ungroup()

, но я должен сделать это более 100 идентификаторов. Мой желаемый результат будет что-то вроде:

    end.goal <- data.frame(ID = c(rep("20180101_HH1_1_1", 8)),
                   species = c("RR", "GS", "SH", "GT", "RR", "BR", "RS", "BA"),
                   bin = c(1, 1, 1, 2, 3, 4, 4, 5),
                   Max_count_of_each_species_in_each_bin = c(11, 66, 500, 1, 6, 12, 30, 6),
                   percent_dist_from_surf = c(11, 15, 5, 33, 42, 68, 71, 100),
                   percent_each_species_max_in_each_bin = c((11/577)*100, (66/577)*100, (500/577)*100, 100, 100, (12/42)*100, (30/42)*100, 100))

Я думал, что, ответив на первоначальный вопрос, я смогу добраться до этого, но теперь я вижу, что вам еще многое нужно сделать, чтобы получить это для каждого идентификатора. ,

Ответы [ 2 ]

0 голосов
/ 31 марта 2020

Вот еще один подход, который не требует, чтобы все oop.

Используя sapply, вы могли cut определять ячейки для каждого значения percent_dist_from_surf в вашем deploy кадре данных.

res <- sapply(deploy$Percent_Column_in_each_bin, function(x) { 
  cut(sp.c$percent_dist_from_surf, seq(0, 100, by = x), include.lowest = TRUE, labels = 1:(100/x))
})
colnames(res) <- deploy$ID
cbind(sp.c, res)

Или используя purrr:

library(purrr)

cbind(sp.c, imap(setNames(deploy$Percent_Column_in_each_bin, deploy$ID), 
     ~ cut(sp.c$percent_dist_from_surf, seq(0, 100, by = .x), include.lowest = TRUE, labels = 1:(100/.x))
))

Выход

   species  ct percent_dist_from_surf 20180101_HH1_1_1 20180101_HH1_1_2 20180101_HH1_1_3
1       RR  25                     11                1                2                1
2       GS  66                     15                1                2                1
3       GT   1                     33                2                4                2
4       BR  12                     68                4                7                3
5       RS  30                     71                4                8                3
6       BA   6                    100                5               10                4
7       GS   1                      2                1                1                1
8       RS  22                     65                4                7                3
9       SH 500                      5                1                1                1
10      RR   6                     42                3                5                2

Редактировать :

Чтобы определить максимальное значение ct для каждого вида, участка и бункера, поместите результат, описанный выше, в кадр данных, называемый res, и выполните следующее.

Сначала приведите в длинную форму с помощью pivot_longer. Затем вы можете group_by вид, участок и корзина и определить максимальный ct для этой комбинации.

library(tidyverse)

res %>%
  pivot_longer(cols = starts_with("2018"), names_to = "site", values_to = "bin") %>%
  group_by(species, site, bin) %>%
  summarise(max_ct = max(ct)) %>%
  arrange(site, bin)

Выход

# A tibble: 26 x 4
# Groups:   species, site [21]
   species site             bin   max_ct
   <fct>   <chr>            <fct>  <dbl>
 1 GS      20180101_HH1_1_1 1         66
 2 RR      20180101_HH1_1_1 1         25
 3 SH      20180101_HH1_1_1 1        500
 4 GT      20180101_HH1_1_1 2          1
 5 RR      20180101_HH1_1_1 3          6
 6 BR      20180101_HH1_1_1 4         12
 7 RS      20180101_HH1_1_1 4         30
 8 BA      20180101_HH1_1_1 5          6
 9 GS      20180101_HH1_1_2 1          1
10 SH      20180101_HH1_1_2 1        500
11 GS      20180101_HH1_1_2 2         66
12 RR      20180101_HH1_1_2 2         25
13 GT      20180101_HH1_1_2 4          1
14 RR      20180101_HH1_1_2 5          6
15 BR      20180101_HH1_1_2 7         12
16 RS      20180101_HH1_1_2 7         22
17 RS      20180101_HH1_1_2 8         30
18 BA      20180101_HH1_1_2 10         6
19 GS      20180101_HH1_1_3 1         66
20 RR      20180101_HH1_1_3 1         25
21 SH      20180101_HH1_1_3 1        500
22 GT      20180101_HH1_1_3 2          1
23 RR      20180101_HH1_1_3 2          6
24 BR      20180101_HH1_1_3 3         12
25 RS      20180101_HH1_1_3 3         30
26 BA      20180101_HH1_1_3 4          6
0 голосов
/ 31 марта 2020

Полезно различать guish между содержимым двух ваших фреймов данных.

  • Кажется, что df2 содержит измерения с некоторых сайтов
  • Кажется, что df1 содержит параметры с помощью которого вы хотите обработать / суммировать измерения в df2

Учитывая эти разные цели двух информационных фреймов, ваш лучший подход, вероятно, состоит в том, чтобы l oop по всем строкам df1 каждый раз добавив столбец к df2. Что-то вроде следующего:

max_dist = max(df2$percent_dist_from_surf)

for(ii in 1:nrow(df1)){

  # extract parameters
  this_ID = df1[[ii,"ID"]]
  this_depth = df1[[ii,"Site_Depth"]]
  this_bins = df1[[ii,"Num_Depth_Bins_Required"]]
  this_percent = df1[[ii,"Percent_Column_in_each_bin"]]

  # add column to df2
  df2 = df2 %>%
    mutate(!!sym(this_ID) := insert_your_calculation_here)
}

Часть кода !!sym(this_ID) := позволяет динамически c именовать ваши выходные столбцы.

И как я могу лучше определить формулу, которую вы хочу за insert_your_calculation_here это ceil(percent_dist_from_surf / max_dist * this_bins)

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