This question already has answers here:
Aggregate / summarize multiple variables per group (e.g. sum, mean)
(10 answers)
Closed 7 years ago.
Say I have a data frame, data That contains multiple sites, indicated by integer site codes. Within those sites are samples from multiple horizons, A,B and C, which have observations of some type, indicated in the column value:
site<- c(12,12,12,12,45,45,45,45)
horizon<-c('A','A','B','C','A','A','B','C')
value<- c(19,14,3,2,18,19,4,5)
comment<- c('pizza','pizza','pizza','pizza','taco','taco','taco','taco')
data<- data.frame(site,horizon,value,comment)
Which looks like this:
site horizon value comment
1 12 A 19 pizza
2 12 A 14 pizza
3 12 B 3 pizza
4 12 C 2 pizza
5 45 A 18 taco
6 45 A 19 taco
7 45 B 4 taco
8 45 C 5 taco
In this case both sites have multiple A observations. I would like to average the values of of duplicate horizons within a site. I would like to retain the comment line within the data frame as well. All observations within a site have the same entry within the comment vector. I would like the output to look like this:
site horizon value comment
1 12 A 16.5 pizza
3 12 B 3 pizza
4 12 C 2 pizza
5 45 A 18.5 taco
7 45 B 4 taco
8 45 C 5 taco
d <- read.table(header=TRUE, text=
' site horizon value comment
1 12 A 19 pizza
2 12 A 14 pizza
3 12 B 3 pizza
4 12 C 2 pizza
5 45 A 18 taco
6 45 A 19 taco
7 45 B 4 taco
8 45 C 5 taco')
merge(aggregate(value ~ site+horizon, FUN=mean, data=d), unique(d[,-3]))
Related
I have a dataset with the reports from a local shop, where each line has a client's ID, date of purchase and total value per purchase.
I want to create a new plot where for each client ID I have all the purchases in the last month or even just sample purchases in a range of dates I choose.
The main problem is that certain customers might buy once a month, while others can come daily - so the number of observations per period of time can vary.
I have tried subsetting my dataset to a specific range of time, but either I choose a specific date - and then I only get a small % of all customers, or I choose a range and get multiple observations for certain customers.
(In this case - I wouldn't mind getting the earliest observation)
An important note: I know how to create a for loop to solve this problem, but since the dataset is over 4 million observations it isn't practical since it would take an extremely long time to run.
A basic example of what the dataset looks like:
ID Date Sum
1 1 1 234
2 1 2 45
3 1 3 1
4 2 4 223
5 3 5 546
6 4 6 12
7 2 1 20
8 4 3 30
9 6 2 3
10 3 5 45
11 7 6 456
12 3 7 65
13 8 8 234
14 1 9 45
15 3 2 1
16 4 3 223
17 6 6 546
18 3 4 12
19 8 7 20
20 9 5 30
21 11 6 3
22 12 6 45
23 14 9 456
24 15 10 65
....
And the new data set would look something like this:
ID 1Date 1Sum 2Date 2Sum 3Date 3Sum
1 1 234 2 45 3 1
2 1 20 4 223 NA NA
3 2 1 5 546 5 45
...
Thanks for your help!
I think you can do this with a bit if help from dplyr and tidyr
library(dplyr)
library(tidyr)
dd %>% group_by(ID) %>% mutate(seq=1:n()) %>%
pivot_wider("ID", names_from="seq", values_from = c("Date","Sum"))
Where dd is your sample data frame above.
This question already has answers here:
Sort (order) data frame rows by multiple columns
(19 answers)
Closed 3 years ago.
I have a very simple dataframe in R:
x <- data.frame("SN" = 1:7, "Age" = c(21,15,22,33,21,15,25), "Name" = c("John","Dora","Paul","Alex","Bud","Chad","Anton"))
My goal is to sort the dataframe by the Age and the Name. I am able to achieve this task partially if i type the following command:
x[order(x[, 'Age']),]
which returns:
SN Age Name
2 2 15 Dora
6 6 15 Chad
1 1 21 John
5 5 21 Bud
3 3 22 Paul
7 7 25 Anton
4 4 33 Alex
As you can see the dataframe is order by the Age but not the Name.
Question: how can i order the dataframe by the age and name at the same time? This is what the result should look like
SN Age Name
6 6 15 Chad
2 2 15 Dora
5 5 21 Bud
1 1 21 John
3 3 22 Paul
7 7 25 Anton
4 4 33 Alex
Note: I would like to avoid to use additional packages but using just the default ones
With dplyr:
library(dplyr)
x %>%
arrange(Age, Name)
SN Age Name
1 6 15 Chad
2 2 15 Dora
3 5 21 Bud
4 1 21 John
5 3 22 Paul
6 7 25 Anton
7 4 33 Alex
x[with(x, order(Age, Name)), ]
SN Age Name
6 6 15 Chad
2 2 15 Dora
5 5 21 Bud
1 1 21 John
3 3 22 Paul
7 7 25 Anton
4 4 33 Alex
This question already has answers here:
Reshaping multiple sets of measurement columns (wide format) into single columns (long format)
(8 answers)
Closed 6 years ago.
I'm cleaning a dataset, but the frame is not ideal, I have to reshape it, but I don't know how. The following are the original data frame:
Rater Rater ID Ratee1 Ratee2 Ratee3 Ratee1.item1 Ratee1.item2 Ratee2.item1 Ratee2.item2 Ratee3.item1 Ratee3.item2
A 12 701 702 800 1 2 3 4 5 6
B 23 45 46 49 3 3 3 3 3 3
C 24 80 81 28 2 3 4 5 6 9
Then I am wondering how to reshape it as the below:
Rater Rater ID Ratee item1 item2
A 12 701 1 2
A 12 702 3 4
A 12 800 5 6
B 23 45 3 3
B 23 46 3 3
B 23 49 3 3
C 24 80 2 3
C 24 81 4 5
C 24 28 6 9
This reshaping is a little bit different from this one (Reshaping data.frame from wide to long format). As I have three parts in the original data.
First part is about the rater's ID (Rater and Rater ID).
The second is about retee's ID (Ratee1, Ratee2, Ratee3).
The Third part is about Rater's rating on each retee (retee*.item1(or2)).
To make it more clear, let me brief the data collecting process.
First, a rater types in his own name and ID,
then nominates three persons (Ratee1 to Ratee3),
and then rates the questions regarding each retee (for each retee, there are two questions).
Does anyone know how to reshape this? Thanks!
We can use melt from data.table
library(data.table)
melt(setDT(df1), measure = patterns("^Ratee\\d+$", "^Ratee\\d+\\.item1",
"^Ratee\\d+\\.item2"), value.name = c("Ratee", "item1", "item2"))[,
variable := NULL][order(Rater)]
# Rater RaterID Ratee item1 item2
#1: A 12 701 1 2
#2: A 12 702 3 4
#3: A 12 800 5 6
#4: B 23 45 3 3
#5: B 23 46 3 3
#6: B 23 49 3 3
#7: C 24 80 2 3
#8: C 24 81 4 5
#9: C 24 28 6 9
This question already has answers here:
Filtering a data frame by values in a column [duplicate]
(3 answers)
Closed 3 years ago.
I have the following data with the ID of subjects.
V1
1 2
2 2
3 2
4 2
5 2
6 2
7 2
8 2
9 2
10 2
11 2
12 2
13 2
14 2
15 2
16 4
17 4
18 4
19 4
20 4
21 4
22 4
23 4
24 4
I want to subset all the rows of the data where V1 == 4. This way I can see which observations relate to subject 4.
For example, the correct output would be
16 4
17 4
18 4
19 4
20 4
21 4
22 4
23 4
24 4
However, the output I'm given after subsetting does not give me the correct rows . It simply gives me.
V1
1 4
2 4
3 4
4 4
5 4
6 4
7 4
8 4
I'm unable to tell which observations relate to subject 4, as observations 1:8 are for subject 2.
I've tried the usual methods, such as
condition<- df == 4
df[condition]
How can I subset the data so I'm given back a dataset that shows the correct row numbers for subject 4.
You can also use the subset function:
subset(df,df$V1==4)
I've managed to find a solution since posting.
newdf <- subset(df, V1 == 4).
However i'm still very interested in other solutions to this problems, so please post if you're aware of another method.
This question already has answers here:
Sort (order) data frame rows by multiple columns
(19 answers)
Closed 7 years ago.
I have the following data frame in R:
DataTable <- data.frame( Name = c("Nelle","Alex","Thomas","Jeff","Rodger","Michi"), Age = c(17, 18, 18, 16, 16, 16), Grade = c(1,5,3,2,2,4) )
Name Age Grade
1 Nelle 17 1
2 Alex 18 5
3 Thomas 18 3
4 Jeff 16 2
5 Rodger 16 2
6 Michi 16 4
Now ill will sort this data frame by its Age column. No problem so far:
DataTable_sort_age <- DataTable[with(DataTable, order(DataTable[,2])),]
Name Age Grade
4 Jeff 16 2
5 Rodger 16 2
6 Michi 16 4
1 Nelle 17 1
2 Alex 18 5
3 Thomas 18 3
There are more persons in the Name columns that have the same age and they should be sorted alphabetically. If the condition, that more than one person is at the same age, is true the data frame should be sorted alphabetically by Name. The output should look like this:
Name Age Grade
1 Jeff 16 2
2 Michi 16 2
3 Rodger 16 4
4 Nelle 17 1
5 Alex 18 5
6 Thomas 18 3
Hope you can help me by sorting the data frame alphabetically.
As per #Stezzo 's comment updating the answer
Just add, DataTable[, 1] in the order function
DataTable[order(DataTable[,2], DataTable[, 1]),]
# Name Age Grade
# 4 Jeff 16 2
# 6 Michi 16 4
# 5 Rodger 16 2
# 1 Nelle 17 1
# 2 Alex 18 5
# 3 Thomas 18 3
Remember, the order in which parameters are passed matters. It would first sort the DataTable dataframe w.r.t 2nd column and in case of a tie it would consider the second parameter which is the first column.
in addition to #Ronak Shah answer you can also use arrange of dplyr.
It looks a bit simpler to me.
arrange(DataTable,Age,Name)
gives
Name Age Grade
1 Alex 16 3
2 Jeff 16 2
3 Michi 16 4
4 Rodger 16 2
5 Nelle 17 1
6 Alex 18 5
7 Thomas 18 4
Here, it first sorts by Age then Name and you can add more variables so on.