2017-08-07 133 views
0

使用dplyr语法,我正在寻找一个“优雅”的方式来mutate新变量到给定的数据帧,其中包含不同时间点的百分比变化。如何一次计算多个变量和时间点的百分比变化?

作为一个例子,考虑以下data.frame包含变量(var.avar.bvar.c)在不同时间点(AB)服用。

set.seed(123) 
df <- data.frame(replicate(6,sample(1:100,50,rep=TRUE))) 
names(df) <- c("A.var.a", "A.var.b", "A.var.c", 
       "B.var.a", "B.var.b", "B.var.c") 

我怎么能计算从A各有关变量的B百分比变化,和mutate他们到数据帧df?我正在寻找dplyr或其他任何可以在包含更多时间点和变量的较大数据框中实施的“智能”解决方案,从而避免逐个输入包含所需输出的新变量。

+1

我想我知道了解决方案,但给我请了几个顶级行从输出数据 – Adamm

回答

1

你可以tidy它,然后聚合每一对。类似于

library(tidyverse) 
df %>% tibble::rowid_to_column() %>% 
    gather(key, value, -rowid) %>% 
    separate(key, c("time", "var"), extra = "merge") %>% # split "A.var.a" into "A" & "var.a" 
    arrange(rowid, var, time) %>% 
    group_by(rowid, var) %>% 
    summarise(diff = diff(value)/value[1]*100) %>% 
    spread(var, diff) 
# # A tibble: 50 x 4 
# # Groups: rowid [50] 
# rowid  var.a  var.b  var.c 
# * <int>  <dbl>  <dbl>  <dbl> 
# 1  1 193.103448 380.00000 -56.66667 
# 2  2 -36.708861 115.55556 -32.35294 
# 3  3 -4.878049 -23.75000 22.44898 
# 4  4 -71.910112 300.00000 -71.87500 
# 5  5 -87.368421 -28.07018 10.20408 
# 6  6 680.000000 323.80952 -12.22222 
# 7  7 9.433962 184.61538 -81.52174 
# 8  8 -75.555556 -61.84211 -32.78689 
# 9  9 -19.642857 -80.00000 14.28571 
# 10 10 -52.173913 -52.63158 480.00000 
# # ... with 40 more rows 

要将列添加到您的原始数据,您可以将%>% ungroup() %>% select(-rowid) %>% rename_all(~paste0("perc_", .x)) %>% bind_cols(df)添加到上述行中。

或尝试在

f <- function(x) { 
    as.list(diff(x, lag=3)/x[1:3]*100) 
} 
df %>% 
    rowwise %>% 
    do(data.frame(perc = f(unlist(.))) 
) %>% 
    bind_cols(df) 
# Source: local data frame [50 x 9] 
# Groups: <by row> 
# 
# # A tibble: 50 x 9 
# perc.B.var.a perc.B.var.b perc.B.var.c A.var.a A.var.b A.var.c B.var.a B.var.b B.var.c 
#   <dbl>  <dbl>  <dbl> <int> <int> <int> <int> <int> <int> 
# 1 193.103448 380.00000 -56.66667  29  5  60  85  24  26 
# 2 -36.708861 115.55556 -32.35294  79  45  34  50  97  23 
# 3 -4.878049 -23.75000  22.44898  41  80  49  39  61  60 
# 4 -71.910112 300.00000 -71.87500  89  13  96  25  52  27 
# 5 -87.368421 -28.07018  10.20408  95  57  49  12  41  54 
# 6 680.000000 323.80952 -12.22222  5  21  90  39  89  79 
# 7  9.433962 184.61538 -81.52174  53  13  92  58  37  17 
# 8 -75.555556 -61.84211 -32.78689  90  76  61  22  29  41 
# 9 -19.642857 -80.00000  14.28571  56  90  42  45  18  48 
# 10 -52.173913 -52.63158 480.00000  46  38  15  22  18  87 
# # ... with 40 more rows 

两个静脉一个横行做法可能需要一些调整...

+0

在哪里'rename_all'函数是从哪里来的? 'dplyr'包? – AJMA

+0

@AJMA是的,它来自'dplyr'。 – lukeA