How to make an histogram with a data frame - r

I was trying to make an histogram of the frequencies of a name list, the list is like this:
> x[1:15,]
X x
1 1 JUAN DOMINGOGONZALEZDELGADO
2 2 FRANCISCO JAVIERVELARAMIREZ
3 3 JUAN CARLOSPEREZMEDINA
4 4 ARMANDOSALINASSALINAS
5 5 JOSE FELIXZAMBRANOAMEZQUITA
6 6 GABRIELMONTIELRIVAS
7 7 DONACIANOSANCHEZHERRERA
8 8 JUAN MARTINXHUERTA
9 9 ALVARO ALEJANDROGONZALEZRAMOS
10 10 OMAR ROMANCASTAƑEDALOPEZ
11 11 IGNACIOBUENOCANO
12 12 RAFAELBETANCOURTDELGADO
13 13 LUIS ALBERTOCASTILLOESCOBEDO
14 14 VICTORHERNANDEZGONZALEZ
15 15 FATIMAROMOTORRES
in order to do that I change it to a frequency table, it looks like this:
> y[1:15,]
X x Freq
1 1 15
2 2 JULIO CESAR ORDAZFLORES 1
3 3 MARCOS ANTONIOCUEVASNAVARRO 1
4 4 DULEY DILTON TRIBOUILLIERLOARCA 1
5 5 ANTONIORAMIREZLOPEZ 2
6 6 BRAYAN ALEJANDROOJEDARAMIREZ 1
7 7 JOSE DE JESUSESCOTOCORTEZ 1
8 8 AARONFLORESGARCIA 1
9 9 ABIGAILNAVARROAMBRIZ 1
10 10 ABILENYRODRIGUEZORTEGA 1
11 11 ABRAHAMHERNANDEZRAMIREZ 1
12 12 ABRAHAMPONCEALCANTARA 1
13 13 ADRIAN VAZQUEZ BUSTAMANTE 2
14 14 ADRIANHERNANDEZBERMUDEZ 28
15 15 ALAN ORLANDOCASTILLALOPEZ 11
when I try hist(x) or hist(x[,2]) I get:
Error in hist.default(x) : 'x' must be numeric
and if I try hist(y[,3]) I got an strange histogram which is not the desired, now how can I make a histogram of the frequencies of the name list?

Related

ordering alpha numeric variable in r

I would like to order a data frame based on an alphanumeric variable. Here how my dataset looks like:
sample.data <- data.frame(Grade=c(4,4,4,4,3,3,3,3,3,3,3,3),
ItemID = c(15,15,15,15,17,17,17,17,16,16,16,16),
common.names = c("15_AS_SA1_Correct","15_AS_SA10_Correct","15_AS_SA2_Correct","15_AS_SA3_Correct",
"17_AS_2_B2","17_AS_2_B1","17_AS_5_C1","17_AS_4_D1",
"16_AS_SA1_Negative","16_AS_SA11_Prediction","16_AS_SA12_UnitMeaning","16_AS_SA3_Complete"))
> sample.data
Grade ItemID common.names
1 4 15 15_AS_SA1_Correct
2 4 15 15_AS_SA10_Correct
3 4 15 15_AS_SA2_Correct
4 4 15 15_AS_SA3_Correct
5 3 17 17_AS_2_B2
6 3 17 17_AS_2_B1
7 3 17 17_AS_5_C1
8 3 17 17_AS_4_D1
9 3 16 16_AS_SA1_Negative
10 3 16 16_AS_SA11_Prediction
11 3 16 16_AS_SA12_UnitMeaning
12 3 16 16_AS_SA3_Complete
I need to order by Grade and ItemID, then by common.names variable that contains alphanumeric.
I used this:
sample.data.ordered <- sample.data %>%
arrange(Grade, ItemID,common.names)
but it did not work for the whole set.
My desired output is:
> sample.data.ordered
Grade ItemID common.names
1 3 16 16_AS_SA1_Negative
2 3 16 16_AS_SA3_Complete
3 3 16 16_AS_SA11_Prediction
4 3 16 16_AS_SA12_UnitMeaning
5 3 17 17_AS_2_B1
6 3 17 17_AS_2_B2
7 3 17 17_AS_4_D1
8 3 17 17_AS_5_C1
9 4 15 15_AS_SA1_Correct
10 4 15 15_AS_SA2_Correct
11 4 15 15_AS_SA3_Correct
12 4 15 15_AS_SA10_Correct
Any thoughts?
Thanks!
A base R solution using order as well as a more complex procedure for common.names involving gsub, regular expression and multiple backreference to match the numbers in the strings by which the column can be ordered:
sample.data[order(sample.data$Grade,
sample.data$ItemID,
as.numeric(gsub(".*(SA|AS_)(\\d+)_(\\w)?(\\d)?.*", "\\2\\4", sample.data$common.names))),]
Grade ItemID common.names
9 3 16 16_AS_SA1_Negative
12 3 16 16_AS_SA3_Complete
10 3 16 16_AS_SA11_Prediction
11 3 16 16_AS_SA12_UnitMeaning
6 3 17 17_AS_2_B1
5 3 17 17_AS_2_B2
8 3 17 17_AS_4_D1
7 3 17 17_AS_5_C1
1 4 15 15_AS_SA1_Correct
3 4 15 15_AS_SA2_Correct
4 4 15 15_AS_SA3_Correct
2 4 15 15_AS_SA10_Correct

How to extract a sample of pairs in grouping variable

My data looks like this:
x y
1 1
2 2
3 2
4 4
5 5
6 6
7 6
8 8
9 9
10 9
11 11
12 12
13 13
14 13
15 14
16 15
17 14
18 16
19 17
20 18
y is a grouping variable. I would like to see how well this grouping went.
Because of this I want to extract a sample of n pairs of cases that are grouped together by variable y
and n pairs of cases that are not grouped together by variable y. In order to calculate the number of
false positives and false negatives (either falsly grouped or not). How do I extract a sample of grouped pairs
and a sample of not-grouped pairs?
I would like the samples to look like this (for n=6) :
Grouped sample:
x y
2 2
3 2
9 9
10 9
15 14
17 14
Not-grouped sample:
x y
1 1
2 2
6 8
6 8
11 11
19 17
How would I go about this in R?
I'm not entirely clear on what you like to do, partly because I feel there is some context missing as to what you're trying to achieve. I also don't quite understand your expected output (for example, the not-grouped sample contains an entry 6 8 that does not exist in your original data...)
That aside, here is a possible approach.
# Maximum number of samples per group
n <- 3;
# Set fixed RNG seed for reproducibility
set.seed(2017);
# Grouped samples
df.grouped <- do.call(rbind.data.frame, lapply(split(df, df$y),
function(x) if (nrow(x) > 1) x[sample(min(n, nrow(x))), ]));
df.grouped;
# x y
#2.3 3 2
#2.2 2 2
#6.6 6 6
#6.7 7 6
#9.10 10 9
#9.9 9 9
#13.13 13 13
#13.14 14 13
#14.15 15 14
#14.17 17 14
# Ungrouped samples
df.ungrouped <- df[sample(nrow(df.grouped)), ];
df.ungrouped;
# x y
#7 7 6
#1 1 1
#9 9 9
#4 4 4
#3 3 2
#2 2 2
#5 5 5
#6 6 6
#10 10 9
#8 8 8
Explanation: Split df based on y, then draw min(n, nrow(x)) samples from subset x containing >1 rows; rbinding gives the grouped df.grouped. We then draw nrow(df.grouped) samples from df to produce the ungrouped df.ungrouped.
Sample data
df <- read.table(text =
"x y
1 1
2 2
3 2
4 4
5 5
6 6
7 6
8 8
9 9
10 9
11 11
12 12
13 13
14 13
15 14
16 15
17 14
18 16
19 17
20 18", header = T)

R: Sum column from table 2 based on value in table 1, and store result in table 1

I am a R noob, and hope some of you can help me.
I have two data sets:
- store (containing store data, including location coordinates (x,y). The location are integer values, corresponding to GridIds)
- grid (containing all gridIDs (x,y) as well as a population variable TOT_P for each grid point)
What I want to achieve is this:
For each store I want loop over the grid date, and sum the population of the grid ids close to the store grid id.
I.e basically SUMIF the grid population variable, with the condition that
grid(x) < store(x) + 1 &
grid(x) > store(x) - 1 &
grid(y) < store(y) + 1 &
grid(y) > store(y) - 1
How can I accomplish that? My own take has been trying to use different things like merge, sapply, etc, but my R inexperience stops me from getting it right.
Thanks in advance!
Edit:
Sample data:
StoreName StoreX StoreY
Store1 3 6
Store2 5 2
TOT_P GridX GridY
8 1 1
7 2 1
3 3 1
3 4 1
22 5 1
20 6 1
9 7 1
28 1 2
8 2 2
3 3 2
12 4 2
12 5 2
15 6 2
7 7 2
3 1 3
3 2 3
3 3 3
4 4 3
13 5 3
18 6 3
3 7 3
61 1 4
25 2 4
5 3 4
20 4 4
23 5 4
72 6 4
14 7 4
178 1 5
407 2 5
26 3 5
167 4 5
58 5 5
113 6 5
73 7 5
76 1 6
3 2 6
3 3 6
3 4 6
4 5 6
13 6 6
18 7 6
3 1 7
61 2 7
25 3 7
26 4 7
167 5 7
58 6 7
113 7 7
The output I am looking for is
StoreName StoreX StoreY SUM_P
Store1 3 6 479
Store2 5 2 119
I.e for store1 it is the sum of TOT_P for Grid fields X=[2-4] and Y=[5-7]
One approach would be to use dplyr to calculate the difference between each store and all grid points and then group and sum based on these new columns.
#import library
library(dplyr)
#create example store table
StoreName<-paste0("Store",1:2)
StoreX<-c(3,5)
StoreY<-c(6,2)
df.store<-data.frame(StoreName,StoreX,StoreY)
#create example population data (copied example table from OP)
df.pop
#add dummy column to each table to enable cross join
df.store$k=1
df.pop$k=1
#dplyr to join, calculate absolute distance, filter and sum
df.store %>%
inner_join(df.pop, by='k') %>%
mutate(x.diff = abs(StoreX-GridX), y.diff=abs(StoreY-GridY)) %>%
filter(x.diff<=1, y.diff<=1) %>%
group_by(StoreName) %>%
summarise(StoreX=max(StoreX), StoreY=max(StoreY), tot.pop = sum(TOT_P) )
#output:
StoreName StoreX StoreY tot.pop
<fctr> <dbl> <dbl> <int>
1 Store1 3 6 721
2 Store2 5 2 119

loop in R to subset from list object ( extract multiple tables from excel sheets)

I need to extract separate tables from each excel sheet and have them as a list object. I have two lists : "allsheets" contains 38 sheets and each of sheets includes at least 2 tables, and "dataRowMeta" contains information about which rows are relevant for each table. For example,
a1 <- data.frame(y1=c(1:15),y2=c(6:20))
a2 <- data.frame(y1=c(3:18),y2=c(2:17))
allsheets <- list(a1, a2)
d1<- data.frame(starthead=c(1,9),endhead=c(2,10),startdata =c(3,11),
enddata = c(7,14),footer = c(8,15))
d2<- data.frame(starthead=c(1,10),endhead=c(2,11),startdata =c(3,12),
enddata = c(8,15),footer = c(9,16))
dataRowMeta <- list(d1,d2)
[[1]]
y1 y2
1 1 6
2 2 7
3 3 8
4 4 9
5 5 10
6 6 11
7 7 12
8 8 13
9 9 14
10 10 15
11 11 16
12 12 17
13 13 18
14 14 19
15 15 20
[[2]]
y1 y2
1 3 2
2 4 3
3 5 4
4 6 5
5 7 6
6 8 7
7 9 8
8 10 9
9 11 10
10 12 11
11 13 12
12 14 13
13 15 14
14 16 15
15 17 16
16 18 17
and here is dataRowMeta :
[[1]]
starthead endhead startdata enddata footer
1 1 2 3 7 8
2 9 10 11 14 15
[[2]]
starthead endhead startdata enddata footer
1 1 2 3 8 9
2 10 11 12 15 16
I've tried to write a loop function which would subset each sheet according to dataRowMeta, but failed to get a desired output.
I am getting an error
Error in sheet[[a[m]:b[m], ]] : incorrect number of subscripts
I guess that's because I am iterating over list, not matrices...but how to tell R to subset list in this case?
So I need 1st and 4th columns of dataRowMeta(starthead and enddata) as "start" and "end" id rows of future tables.
tables <- function(allsheets,dataRowMeta){
for(i in 1 : length(dataRowMeta)){
for (j in 1 : nrow(dataRowMeta[[i]])){
a <-""
b <- ""
a <- dataRowMeta[[i]][j:j,1]
b <- dataRowMeta[[i]][j:j,4]
for (k in 1 : length(allsheets)){
sheet <- allsheets[k]
for ( m in 1 : length(a)){
tbl <- sheet[[a[m]:b[m],]]
}
}
}
}}
Desired output : I have this for the first element of the first list(sheet1):
sheet1 <- allsheets[[1]]
tmp1 <- sheet1[dataRowMeta[[1]][1:1,1] :dataRowMeta[[1]][1:1,4] ,]
> tmp1
y1 y2
1 1 6
2 2 7
3 3 8
4 4 9
5 5 10
6 6 11
7 7 12
And need a loop which would do it for all sheets. Please help me to figure out how to get it. Thank you!

dplyr summarise over nested group_by [duplicate]

This question already has answers here:
How to sum a variable by group
(18 answers)
Closed 4 years ago.
I have a data frame like this:
Date Amount Category
1 02.07.15 1 1
2 02.07.15 2 1
3 02.07.15 3 1
4 02.07.15 4 2
5 03.07.15 5 2
6 04.07.15 6 3
7 05.07.15 7 3
8 06.07.15 8 3
9 07.07.15 9 4
10 08.07.15 10 5
11 09.07.15 11 6
12 10.07.15 12 4
13 11.07.15 13 4
14 12.07.15 14 5
15 13.07.15 15 5
16 14.07.15 16 6
17 15.07.15 17 6
18 16.07.15 18 5
19 17.07.15 19 4
I would like to calculate the sum of the amount for each single day in a category. My attempts like (see the code) are both not sufficient.
summarise(group_by(testData, Category), sum(Amount))
Wrong output --> here the sum is calculated over each group
Category sum(Amount)
1 1 6
2 2 9
3 3 21
4 4 53
5 5 57
6 6 44
summarise(group_by(testData, Date), sum(Amount), categories = toString(Category))
Wrong output --> here the sum is calculated over each day but the categories are not considered
Date sum(Amount) categories
1 02.07.15 10 1, 1, 1, 2
2 03.07.15 5 2
3 04.07.15 6 3
4 05.07.15 7 3
5 06.07.15 8 3
6 07.07.15 9 4
7 08.07.15 10 5
8 09.07.15 11 6
9 10.07.15 12 4
10 11.07.15 13 4
11 12.07.15 14 5
12 13.07.15 15 5
13 14.07.15 16 6
14 15.07.15 17 6
15 16.07.15 18 5
16 17.07.15 19 4
So far I did not succeed in combining both statements.
How can I nest both group_by statements to calculate the sum of the amount for each single day in each category?
Nesting the groups like:
summarise(group_by(group_by(testData, Date), Category), sum(Amount), dates = toString(Date))
Category sum(Amount) dates
1 1 6 02.07.15, 02.07.15, 02.07.15
2 2 9 02.07.15, 03.07.15
3 3 21 04.07.15, 05.07.15, 06.07.15
4 4 53 07.07.15, 10.07.15, 11.07.15, 17.07.15
5 5 57 08.07.15, 12.07.15, 13.07.15, 16.07.15
6 6 44 09.07.15, 14.07.15, 15.07.15
does not work as intended.
I have heard of dplyr - summarise weighted data summarise_each but could not get it to work:
summarise_each(testData, funs(Category))
Error could not find function Category
You can try
testData %>%
group_by(Date,Category) %>%
summarise(Amount= sum(Amount))

Resources