2014-09-24 66 views
0

我需要在R中轉置一個df並且聚合函數必須爲min。具有聚合最小函數的R- reshape2

例子:

library(reshape2) 
N <- 20 
df <- data.frame(rutcli=sample(101:103, N, replace=T), 
      mes_atras=sample(1:4, N, replace=T), pay_day=sample(1:30, N, replace=T)) 


s<-dcast(df, rutcli ~ mes_atras, fun.aggregate = min, value.var = 'pay_day') 
View(s) 

但我得到一個警告:

警告消息:在.fun(.value的[0],...):沒有非缺失參數 分鐘;返回天道酬勤

而結果是不希望的:

rutcli 1 2 3 4 
    101 1 1 Inf 1 
    102 Inf 2 14 8 
    103 3 6 2 25 

我怎樣才能解決這個問題?

謝謝

+0

你應該給實際的數據幀(用'dput')或設置一個隨機的種子,以使你想要的結果可重現。 – 2014-09-24 04:03:03

回答

1

您收到警告是因爲您要求提供一個空集的最小值。例如,沒有pay_day的值,其中rutcli = 102和mes_atras = 1,因此返回Inf

如果您設置fun.aggregate=length,您可以更容易地看到這一點。例如:

library(reshape2) 
N <- 20 

set.seed(11) # To make the `sample` function reproducible 
df <- data.frame(rutcli=sample(101:103, N, replace=T), 
       mes_atras=sample(1:4, N, replace=T), 
       pay_day=sample(1:30, N, replace=T)) 

dcast(df, rutcli ~ mes_atras, fun.aggregate = length, value.var = 'pay_day') 

    rutcli 1 2 3 4 
1 101 4 4 2 0 
2 102 1 3 1 0 
3 103 2 2 0 1 

的零點代表其中不存在的pay_dayrutclimes_atras組合。如果我們用min功能這個數據幀上運行dcast,我們會得到Inf在零點出現:

dcast(df, rutcli ~ mes_atras, fun.aggregate = min, value.var = 'pay_day') 

    rutcli 1 2 3 4 
1 101 1 5 7 Inf 
2 102 18 13 14 Inf 
3 103 10 13 Inf 7 
Warning message: 
In .fun(.value[0], ...) : no non-missing arguments to min; returning Inf 

可以使用的拆分申請-結合的方法之一獲得NA而不是Inf。 @MatthewLundberg給出了一個基地R的方法。這裏有一個與dplyr

library(dplyr) 

df %>% 
    group_by(rutcli, mes_atras) %>% 
    summarise(min_pay_day=min(pay_day)) %>% 
    dcast(rutcli ~ mes_atras, value.var="min_pay_day") 

    rutcli 1 2 3 4 
1 101 1 5 7 NA 
2 102 18 13 14 NA 
3 103 10 13 NA 7 
+0

或者使用'dplyr'和'tidyr'組合並用'spread(mes_atras,min_pay_day)'替換最後一行' – akrun 2014-09-24 04:33:26

1

您可以aggregatereshape從包裝stats做到這一點:

reshape(
     aggregate(pay_day ~ mes_atras + rutcli, data=df, FUN=min), 
     direction='wide', timevar='mes_atras', idvar='rutcli' 
) 
## rutcli pay_day.1 pay_day.2 pay_day.3 pay_day.4 
## 1 101   1  20  15   2 
## 5 102  18  30  NA   3 
## 8 103   2   5  23  16 

如果需要,可以與Inf替換NA值。

這裏是我的df

structure(list(rutcli = c(103L, 103L, 103L, 103L, 103L, 103L, 
102L, 102L, 103L, 102L, 101L, 101L, 101L, 101L, 101L, 103L, 102L, 
101L, 101L, 103L), mes_atras = c(1L, 3L, 4L, 1L, 1L, 2L, 1L, 
4L, 1L, 2L, 2L, 4L, 3L, 2L, 2L, 4L, 4L, 4L, 1L, 2L), pay_day = c(3L, 
23L, 16L, 18L, 2L, 5L, 18L, 3L, 12L, 30L, 20L, 2L, 15L, 24L, 
29L, 24L, 3L, 19L, 1L, 12L)), .Names = c("rutcli", "mes_atras", 
"pay_day"), row.names = c(NA, -20L), class = "data.frame") 
0

我做到了:

my.min <- function (v) {if (length(v) == 0) 0 else min(v)} 
s<-dcast(df, rutcli ~ mes_atras, fun.aggregate = my.min, value.var = 'pay_day') 

而且因爲我知道,我沒有任何0: 小號[S == 0] < - NA