Примените пользовательскую функцию с суммированием dplyr для многих уникальных измерений - PullRequest
0 голосов
/ 28 августа 2018

Я хотел бы рассчитать процентное изменение площади (между временами T1 и T9) для разных людей между различными уровнями горячей и холодной температурной обработки.

Некоторые примеры данных:

library(dplyr)

Individual<-c("a1.2", "a1.2","bd3.d","bd3.d", "k20.d","k20.d", "dfd.2","dfd.2", "d3.d","d3.d", "df3.1","df3.1")
Treat <- c('hot','hot','hot','hot','hot','hot','cold',"cold",'cold',"cold",'cold',"cold")
Time <- c("T1", "T9", "T1", "T9","T1", "T9","T1", "T9","T1", "T9","T1", "T9")
Area<- c("0.1", "0.5", "0.1", "0.645","0.1", "0.54","0.1", "0.587","0.1", "0.78","0.23", "0.78")
df.Area <- data.frame(Individual, Treat,Time,Area)
head(df.Area, n=20)

head(df.Area, n=20)
   Individual Treat Time  Area
1        a1.2   hot   T1   0.1
2        a1.2   hot   T9   0.5
3       bd3.d   hot   T1   0.1
4       bd3.d   hot   T9 0.645
5       k20.d   hot   T1   0.1
6       k20.d   hot   T9  0.54
7       dfd.2  cold   T1   0.1
8       dfd.2  cold   T9 0.587
9        d3.d  cold   T1   0.1
10       d3.d  cold   T9  0.78
11      df3.1  cold   T1  0.23
12      df3.1  cold   T9  0.78

Например: (T9-T1 / T9) * 100

Сначала найдите тех же самых индивидуумов, например, a1.2 в строках 1 и 2, сделайте расчет между T9 и T1: (0,5-0,1 / 0,1) * 100 = увеличение на 400%.

Вывод будет:

       Individual Treat Ch.Area  
    1        a1.2   hot    400    
    2        bd3.d  hot     num.etc 
    3       k20.d   hot     num.etc 
    4       dfd.2   cold    num.etc
    5       d3.d    cold    num.etc ....

df1 <- df.Area %>% group_by(Treat, Time, Individual)

Это дикое предположение о структуре:

df2 <- df1 %>%  summarise(Ch.Area = T9[!Individual == "??"] - T1[!Individual == "??"])/T9([!Individual == "??"])*100)

Я бы хотел, чтобы dplyr сгруппировал каждого человека с одинаковым именем вместе, чтобы вычислить процент, при этом сохраняя групповую переменную Treat. Это возможно? Я также рад использовать другой пакет / метод, если лучше.

Любая помощь будет отличной!

Ответы [ 3 ]

0 голосов
/ 28 августа 2018
library(dplyr)
df.Area %>%  mutate_at('Area', as.numeric) %>% 
             group_by(Individual,Treat) %>% 
             summarise(Ch.Area = (Area[Time=='T9']/Area[Time=='T1']-1)*100)


# A tibble: 6 x 3
# Groups:   Individual [?]
Individual Treat Ch.Area
<chr>      <chr>   <dbl>
1 a1.2       hot      400 
2 bd3.d      hot      545 
3 d3.d       cold     680 
4 df3.1      cold     239.
5 dfd.2      cold     487.
6 k20.d      hot      440.
0 голосов
/ 28 августа 2018

Использование dplyr:

Решение 1: Предполагая, что T9 всегда имеет более высокие значения для переменной области, чем T1

Individual<-c("a1.2", "a1.2","bd3.d","bd3.d", "k20.d","k20.d", "dfd.2","dfd.2", "d3.d","d3.d", "df3.1","df3.1")
Treat <- c('hot','hot','hot','hot','hot','hot','cold',"cold",'cold',"cold",'cold',"cold")
Time <- c("T1", "T9", "T1", "T9","T1", "T9","T1", "T9","T1", "T9","T1", "T9")
Area<- c("0.1", "0.5", "0.1", "0.645","0.1", "0.54","0.1", "0.587","0.1", "0.78","0.23", "0.78")

df <- data.frame(Individual, Treat,Time, Area)

df %>%
  group_by(Individual) %>%
  mutate(Ch.Area = ((last(as.numeric(as.character(Area)))-first(as.numeric(as.character(Area))))/first(as.numeric(as.character(Area))))*100) %>% #Setting them as.numeric because in your data.frame they are stored as factors 
  summarise(Treat = last(Treat),
            Ch.Area = last(Ch.Area))

# A tibble: 6 x 3
  Individual Treat Ch.Area
  <fct>      <fct>   <dbl>
1 a1.2       hot      400.
2 bd3.d      hot      545.
3 d3.d       cold     680.
4 df3.1      cold     239.
5 dfd.2      cold     487.
6 k20.d      hot      440.

Решение 2. Не предполагая, что T9 всегда имеет более высокие значения для переменной Area, чем T1

df %>%
  group_by(Individual) %>%
  mutate(Ch.Area = ((as.numeric(as.character(Area[Time=="T9"]))-as.numeric(as.character(Area[Time=="T1"])))/as.numeric(as.character(Area[Time=="T1"])))*100) %>% 
  summarise(Treat = last(Treat),
            Ch.Area = last(Ch.Area))

# A tibble: 6 x 3
  Individual Treat Ch.Area
  <fct>      <fct>   <dbl>
1 a1.2       hot      400.
2 bd3.d      hot      545.
3 d3.d       cold     680.
4 df3.1      cold     239.
5 dfd.2      cold     487.
6 k20.d      hot      440.
0 голосов
/ 28 августа 2018

Вот опция tidyverse, которая использует немного изменения формы:

library(tidyverse)

Individual<-c("a1.2", "a1.2","bd3.d","bd3.d", "k20.d","k20.d", "dfd.2","dfd.2", "d3.d","d3.d", "df3.1","df3.1")
Treat <- c('hot','hot','hot','hot','hot','hot','cold',"cold",'cold',"cold",'cold',"cold")
Time <- c("T1", "T9", "T1", "T9","T1", "T9","T1", "T9","T1", "T9","T1", "T9")
Area<- c("0.1", "0.5", "0.1", "0.645","0.1", "0.54","0.1", "0.587","0.1", "0.78","0.23", "0.78")
df.Area <- data.frame(Individual, Treat,Time,Area)

df.Area %>%
  spread(Time, Area, convert = T) %>%
  mutate(Ch.Area = 100*(T9/T1-1))

#   Individual Treat   T1    T9  Ch.Area
# 1       a1.2   hot 0.10 0.500 400.0000
# 2      bd3.d   hot 0.10 0.645 545.0000
# 3       d3.d  cold 0.10 0.780 680.0000
# 4      df3.1  cold 0.23 0.780 239.1304
# 5      dfd.2  cold 0.10 0.587 487.0000
# 6      k20.d   hot 0.10 0.540 440.0000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...