每个分位数的变换表

时间:2019-07-09 15:04:49

标签: r dplyr

我有一个关于您的技术问题。

我有此数据形式:

 Month <- c(1,2,3,4,5,6)
    Typ <- c(1,1,1,1,1,1)
    nb_obs <- c(5,5,5,5,5,5)
    V1 <- c(369,    392,    352,    366,    352,    345)
    V2 <- c(525,    490,    473,    480,    475,    513)
    V3 <- c(680,    651,    664,    640,    621,    656)
    V4 <- c(727,    765,    690,    729,    753,    727)
    V5 <- c(580,    578,    553,    503,    542,    539)
    data <- cbind(Month, Typ, nb_obs, V1, V2, V3, V4, V5)

 Month Typ nb_obs  V1  V2  V3  V4  V5
[1,]     1   1      5 369 525 680 727 580
[2,]     2   1      5 392 490 651 765 578
[3,]     3   1      5 352 473 664 690 553
[4,]     4   1      5 366 480 640 729 503
[5,]     5   1      5 352 475 621 753 542
[6,]     6   1      5 345 513 656 727 539

在我的真实数据中,我有1000列。我想对这张表进行转换,以便将中位数以及“ Vx”变量的分位数作为新列。喜欢:

Month <- c(1,2,3,4,5,6)
Typ <- c(1,1,1,1,1,1)
nb_obs <- c(5,5,5,5,5,5)
median <- c(median(V1), median(V2), median(V3), median(V4), median(V5))
born_20 <- c(quantile(V1, probs = c(0.20)), quantile(V2, probs = c(0.20)), quantile(V3, probs = c(0.20)), quantile(V4, probs = c(0.20)),quantile(V5, probs = c(0.20)))
data_2 <- cbind(Month, Typ, nb_obs, median, born_20)

 Month Typ nb_obs median born_20%
[1,]     1   1      5  359.0     352
[2,]     2   1      5  485.0     475
[3,]     3   1      5  653.5     640
[4,]     4   1      5  728.0     727
[5,]     5   1      5  547.5     539
[6,]     6   1      5  359.0     352

我希望有一列0.40,0.80; 0.30,0.70; 0.20、0.80; 0.05,0.95。这些是我用geom_ribbon制作ggplot的时间间隔。您可以使用dplyr软件包获得解决方案吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

我们可以在base R中进行此操作,方法是用sapply循环浏览感兴趣的列,然后将功能(medianquantile)应用于这些列

i1 <- startsWith(names(data), "V")
sapply(data[i1], function(x) c(Median = median(x), q02 = quantile(x, 0.2)))
#        V1  V2    V3  V4    V5
#Median  359 485 653.5 728 547.5
#q02.20% 352 475 640.0 727 539.0

数据

data <- structure(list(Month = c(1, 2, 3, 4, 5, 6), Typ = c(1, 1, 1, 
1, 1, 1), nb_obs = c(5, 5, 5, 5, 5, 5), V1 = c(369, 392, 352, 
366, 352, 345), V2 = c(525, 490, 473, 480, 475, 513), V3 = c(680, 
651, 664, 640, 621, 656), V4 = c(727, 765, 690, 729, 753, 727
), V5 = c(580, 578, 553, 503, 542, 539)), 
class = "data.frame", row.names = c(NA, 
-6L))

答案 1 :(得分:1)

好像您想按列执行计算。我们可以使用summarise_at来汇总多个列并应用不同的功能。

library(dplyr)
data %>%
  summarise_at(vars(starts_with("V")), 
              list(new = ~median(.), q02 = ~quantile(., 0.2)))

#  V1_new V2_new V3_new V4_new V5_new V1_q02 V2_q02 V3_q02 V4_q02 V5_q02
#1    359    485  653.5    728  547.5    352    475    640    727    539

要重构数据,我们可以使用gatherspread

library(dplyr)
library(tidyr)

data %>%
    summarise_at(vars(starts_with("V")), 
            list(median = ~median(.), q02 = ~quantile(., 0.2))) %>%
    gather(key, value) %>%
    separate(key, c("col", "prop"), sep = "_") %>%
    spread(prop, value)

#  col median q02
#1  V1  359.0 352
#2  V2  485.0 475
#3  V3  653.5 640
#4  V4  728.0 727
#5  V5  547.5 539

如果需要,您可以在同一quantile通话中添加更多summarise_at通话。

数据

Month <- c(1,2,3,4,5,6)
Typ <- c(1,1,1,1,1,1)
nb_obs <- c(5,5,5,5,5,5)
V1 <- c(369,    392,    352,    366,    352,    345)
V2 <- c(525,    490,    473,    480,    475,    513)
V3 <- c(680,    651,    664,    640,    621,    656)
V4 <- c(727,    765,    690,    729,    753,    727)
V5 <- c(580,    578,    553,    503,    542,    539)
data <- data.frame(Month, Typ, nb_obs, V1, V2, V3, V4, V5)