2017-09-11 2 views
2

Ich habe Daten wie folgt aus:Aggregate von paymentamount

emailaddress customer_acquisation_date customer_order_date payment_amount 
[email protected]  01/05/2013 6:24 AM   01/05/2013 5:10 AM   $ 20.67 
[email protected]  01/05/2013 6:24 AM   02/07/2013 7:21 PM   $ 25.56 
[email protected]  01/05/2013 6:24 AM   07/10/2013 8:00 AM   $100.00 
[email protected]  01/05/2013 6:24 AM   08/12/2013 9:35 AM   $30.00 

I (Zahlungsbetrag) zu summieren, ich versuche, durch E-Mailadresse, wo ich die endgültige Ausgabe wollen als:

emailaddress customer_acquisation_date customer_order_date payment_amount 
[email protected]  01/05/2013 6:24 AM   01/05/2013   $ 177 
              02/07/2013     
              07/10/2013     
              08/12/2013 

Code Ich schreibe

z <- aggregate(x$emailaddress~x$paymentamount,data=x,FUN=sum) 

Fehler ich erhalte

Error in Summary.factor(c(211594L, 291939L, 79240L, 208971L, 369325L, : 
    ‘sum’ not meaningful for factors 

Was ist der richtige Weg, dies zu tun. Irgendwelche Hilfe wird geschätzt

Antwort

6

Die Aggregatfunktion nimmt zuerst einen Wert aggregieren auf, dann die Gruppierung Argument. Wie bereits erwähnt, müssen Sie auch das Dollarzeichen entfernen, um die Spalte in ein numerisches Format konvertieren zu können.

# Remove the dollar sign 
x$payment_amount = as.numeric(gsub('[$]', '', x$payment_amount)) 

# Write it in the right order .. aggregate(x, by, FUN ..) 
z <- aggregate(payment_amount ~ emailaddress, data = x, FUN = sum) 

Edit: Hinzufügen einer data.table Lösung, die anderen Spalten als auch zu halten.

library(data.table) 
setDT(x) # Convert the data.frame to data.table 
z = x[, payment_total := sum(payment_amount), by = emailaddress] 
setDF(z) # Convert the result to data.frame 
+0

Nizza - viel schnellere data.table Lösung +1 – www

0

Wir konnten Zeichen oder Faktor zusammen nicht hinzufügen. Wir müssen den Faktor in Zeichen konvertieren, $ entfernen und dann in numerisch konvertieren.

library(dplyr) 
library(stringr) 

x2 <- x %>% 
    mutate(payment_amount = as.character(payment_amount)) %>% 
    mutate(payment_amount = str_replace(payment_amount, fixed("$"), "")) %>% 
    mutate(payment_amount = as.numeric(payment_amount)) %>% 
    group_by(emailaddress) %>% 
    summarise(payment_amount = sum(payment_amount)) 

x2 
# A tibble: 1 x 2 
    emailaddress payment_amount 
     <fctr>   <dbl> 
1 [email protected]   176.23 

Daten

x <- read.table(text = "emailaddress customer_acquisation_date customer_order_date payment_amount 
[email protected]  '01/05/2013 6:24 AM'   '01/05/2013 5:10 AM'   '$ 20.67' 
       [email protected]  '01/05/2013 6:24 AM'   '02/07/2013 7:21 PM'   '$ 25.56' 
       [email protected]  '01/05/2013 6:24 AM'   '07/10/2013 8:00 AM'   '$100.00' 
       [email protected]  '01/05/2013 6:24 AM'   '08/12/2013 9:35 AM'   '$30.00'", 
       header = TRUE) 
+0

Thanku für Lösung, aber es gibt mir Fehler bei x%>% mutieren (paymentamount = wie.character (paymentmount))%>%: konnte die Funktion "%>%" nicht finden – sim

+0

@sim Sie müssen das 'dplyr' Paket mit' library (dplyr) laden ' – useR

+0

Haben Sie das' dplyr' Paket von 'library geladen (dplyr) '? – www

0

Ich würde vorschlagen, readr verwenden, dplyr und lubridate:

library(tidyverse) 
library(lubridate) 

data_string <- trimws(' 
email  , datetime   , payment 
[email protected] , 01/05/2013 5:10 AM , $20.67 
[email protected] , 02/07/2013 7:21 PM , $25.56 
[email protected] , 07/10/2013 8:00 AM , $100.00 
[email protected] , 08/12/2013 9:35 AM , $30.00 
') 

orders <- read_csv(data_string, col_types = cols(
    email = col_character(), 
    datetime = col_datetime(format = "%m/%d/%Y %I:%M %p"), 
    payment = col_number() 
)) 
orders 

## # A tibble: 4 x 3 
##   email   datetime payment 
##   <chr>    <dttm> <dbl> 
## 1 [email protected] 2013-01-05 05:10:00 20.67 
## 2 [email protected] 2013-02-07 19:21:00 25.56 
## 3 [email protected] 2013-07-10 08:00:00 100.00 
## 4 [email protected] 2013-08-12 09:35:00 30.00 

customers <- orders %>% 
    group_by(email) %>% 
    summarise(
     total_payment = sum(payment), 
     acquisition_date = min(datetime), 
     order_dates = list(date(datetime)) 
    ) 
customers 

## # A tibble: 1 x 4 
##   email total_payment acquisition_date order_dates 
##   <chr>   <dbl>    <dttm>  <list> 
## 1 [email protected]  176.23 2013-01-05 05:10:00 <date [4]> 

customers$order_dates 

## [[1]] 
## [1] "2013-01-05" "2013-02-07" "2013-07-10" "2013-08-12" 
2

Anstatt die $ Zeichen zu entfernen, werden die folgenden Auszüge den numerischen Wert direkt. Dies hat den Vorteil, dass nicht spezifiziert werden muss, was tatsächlich entfernt werden soll (z. B. unterschiedliche Währungszeichen oder "10,00 USD"). Ich habe hinzugefügt merge auch genau OPs gewünschte Ausgabe zu erhalten (nicht wirklich, aber besser IMHO):

library(magrittr) 
library(dplyr) 

x$payment_amount %<>% {regmatches(., gregexpr("[[:digit:]]+[.][[:digit:]]+", .))} %>% 
    as.numeric() 

aggre = aggregate(payment_amount ~ emailaddress, data = df, FUN = sum) 

select(x, -payment_amount) %>% 
    merge(aggre, by = "emailaddress") %>% 
    rename(tot_payment_amount = payment_amount) 

Ergebnis:

emailaddress customer_acquisation_date customer_order_date tot_payment_amount 
1 [email protected]  01/05/2013 6:24 AM 01/05/2013 5:10 AM    176.23 
2 [email protected]  01/05/2013 6:24 AM 02/07/2013 7:21 PM    176.23 
3 [email protected]  01/05/2013 6:24 AM 07/10/2013 8:00 AM    176.23 
4 [email protected]  01/05/2013 6:24 AM 08/12/2013 9:35 AM    176.23 

Hinweis:

Ich benutzte das magrittr Paket vor allem für es ist bequem zwei-Wege-Pipe-Operator %<>%. Dies speist die LHS() zu . auf der RHS und setzt die LHS gleich der Ausgabe von RHS. {} um regmatches ist erforderlich, um x$payment_amount in eine Funktion innerhalb einer Funktion (d. H. text= Argument von gregexpr das ist innerhalb regmatches). Für diejenigen, die hier %<>% zu sein verwirrend ist, wie das gleiche zu tun, ohne %<>%:

x$payment_amount = 
    with(x, regmatches(payment_amount, gregexpr("[[:digit:]]+[.][[:digit:]]+", payment_amount))) %>% 
    as.numeric()