How many combinatioons are possible? - math

I have 4 numbers 0, 1, 2, 3 How many combinations of 3 digits can I make? Numbers can be repeated.
example
000
001
011
111
324
123 etc etc

4 to the third power
4^3 = 64 combinations
to get all combinations run something like
digits = [0, 1, 2, 3]
for i in digits:
for j in digits:
for k in digits:
print("{} {} {}".format(i, j, k))

Related

index from one vector to another by closest values

Given two sorted vectors, how can you get the index of the closest values from one onto the other.
For example, given:
a = 1:20
b = seq(from=1, to=20, by=5)
how can I efficiently get the vector
c = (1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4)
which, for each value in a, provides the index of the largest value in b that is less than or equal to it. But the solution needs to work for unpredictable (though sorted) contents of a and b, and needs to be fast when a and b are large.
You can use findInterval, which constructs a sequence of intervals given by breakpoints in b and returns the interval indices in which the elements of a are located (see also ?findInterval for additional arguments, such as behavior at interval boundaries).
a = 1:20
b = seq(from = 1, to = 20, by = 5)
findInterval(a, b)
#> [1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4
We can use cut
as.integer(cut(a, breaks = unique(c(b-1, Inf)), labels = seq_along(b)))
#[1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4

collapse/aggregate some parts of an adjacency matrix simultaneously on rows and columns

I have a matrix, which represents mobility between various jobs:
jobnames <- c("job 1","job 2","job 3","job 4","job 5","job 6","job 7")
jobdat <- matrix(c(
5, 5, 5, 0, 0, 5, 5,
5, 5, 2, 5, 5, 1, 5,
1, 5, 5, 5, 0, 0, 1,
1, 0, 5, 5, 8, 0, 1,
0, 5, 0, 0, 5, 5, 1,
0, 0, 5, 5, 0, 5, 5,
0, 1, 0, 0, 5, 1, 5
),
nrow = 7, ncol = 7, byrow = TRUE,
dimnames = list(jobnames,jobnames
))
This is treated as a directed, weighted adjacency matrix in a social network analysis. The direction of the network is from rows to columns: So mobility is defined as going from a job-row to a job-column. The diagonal is relevant, since it is possible to change to the same job in another firm.
I need to collapse this matrix according to a prefigured list
containing the index of the jobs that should be combined:
group.list <- list(grp1=c(1,2) ,grp2 =c(3,4))
Now, since it is an adjacency matrix, it's a bit different than the other ' answers about how to collapse a matrix that I've ' found here and elsewhere. The collapse has to be simultanious on both the rows and the columns. And some jobs isn't grouped at all. So the result in this example should be like this:
group.jobnames <- c("job 1 and 2","job 3 and 4","job 5","job 6","job 7")
group.jobdat <- matrix(c(
20,12,5,6,10,
7,17,8,0,2,
5,0,5,5,1,
0,10,0,5,5,
1,0,5,1,5
),
nrow = 5, ncol = 5, byrow = TRUE,
dimnames = list(group.jobnames,group.jobnames
))
This example groups the two first jobs and then the next two, but in my actual data it could be any combination of (indexes of) jobs, and any number of jobs in each group. So job [1,7] could be one group, and job [2,3,6] could be another group, while job 4 or 5 wasn't grouped. Or any other combination.
Thank you for your time,
I believe there are some typos in the intended output, and the group.list definition. If I am correct in my interpretation, here is a solution.
Here is a new group.list to conform with the names of the desired output. In this version, group 2 is mapped to 1 and group 4 is mapped to 3, which conforms with the text in group.jobs.
group.list <- list(grp1=c(1, 3), grp2=c(2, 4))
Given this list, construct a grouping vector
# initial grouping
groups <- seq_len(ncol(jobdat))
# map elements of second list item to values of first list item
groups[match(group.list[["grp2"]], groups)] <- group.list[["grp1"]]
groups
[1] 1 1 3 3 5 6 7
So, now groups 1 and 2 are the same as well as 3 and 4. Now, we use rowsum and a couple of transposes to calculate the output.
myMat <- t(rowsum(t(rowsum(jobdat, groups)), groups))
# add the group names
dimnames(myMat) <- list(group.jobnames,group.jobnames)
myMat
job 1 and 2 job 3 and 4 job 5 job 6 job 7
job 1 and 2 20 12 5 6 10
job 3 and 4 7 20 8 0 2
job 5 5 0 5 5 1
job 6 0 10 0 5 5
job 7 1 0 5 1 5
In response to the OP's comments below, the grouping was intended to be within list elements, rather than corresponding positions between list elements as I had originally interpreted. To accomplish this form a grouping, a repeated feeding of replace to Reduce will accomplish the task.
With group.list as in the question,
group.list <- list(grp1=c(1, 2), grp2=c(3, 4))
groups <- Reduce(function(x, y) replace(x, x[x %in% y], min(y)),
c(list(groups), unname(group.list)))
groups
[1] 1 1 3 3 5 6 7
Here, replace takes the original grouping, finds the elements in the grouping that are in one of the vectors in group.list, and replaces these with the minimum value of that vector. The Reduce function repeatedly applies this operation on the original group variable, except modifying it in each iteration.
With this result, we use the above transposes and rowsum to get
myMat
job 1 and 2 job 3 and 4 job 5 job 6 job 7
job 1 and 2 20 12 5 6 10
job 3 and 4 7 20 8 0 2
job 5 5 0 5 5 1
job 6 0 10 0 5 5
job 7 1 0 5 1 5

R Multiplying a list of lists with a vector

I have a dataframe with 1 column consisting of 10 lists each with a varying number of elements. I also have a vector with 10 different values in it (10 integers).
I want to take the "sumproduct" of each 10 lists with its corresponding vector value, and end up with 10 values.
Value 1 = sumproduct(First list, First vector value)
Value 2 = sumproduct(Second list, Second vector value)
etc...
Final_Answer <- c(Value 1, Value 2, ... , Value 10)
I have a function that generates the dataframe containing lists of numbers representing years. The dataframe is contructed using a loop to generate each value then rowbinding the value together with the dataframe.
Time_Function <- function(Maturity)
{for (i in 0:Count)
{x<-as.numeric(((as.Date(as.Date(Maturity)-i*365)-Start_Date)/365)
Time <- rbind(Time, data.frame(x))}
return((Time))
}
The result is this:
http://pastebin.com/J6phR2hv
http://i.imgur.com/Sf4mpA5.png
If my vector looks like [1,2,3,4...,10], I want the output to be:
Final Answer = [(1*1.1342466 + 1*0.6342466 + 1* 0.1342466), (2*1.3835616 + 2*0.8835616 + 2*0.3835616), ... , ( ... +10*0.0630137)]
Assuming you want to multiply each value in the list by the respective scalar and then add it all up, here is one way to do it.
list1 <- mapply(rep, 1:10, 10:1)
vec1 <- 1:10
df <- data.frame( I(list1), vec1)
df
list1 vec1
1 1, 1, 1,.... 1
2 2, 2, 2,.... 2
3 3, 3, 3,.... 3
4 4, 4, 4,.... 4
5 5, 5, 5,.... 5
6 6, 6, 6,.... 6
7 7, 7, 7, 7 7
8 8, 8, 8 8
9 9, 9 9
10 10 10
mapply(df$list1, df$vec1, FUN = function(x, y) {y* sum(x)})
[1] 10 36 72 112 150 180 196 192 162 100

Order function returns different values as vector

I want to rearrange this vector decreasingly:
x <- c(10, 10, 7, 3, 6, 2, 2, 7, 8, 1, 3, 1, 1, 1, 5, 5, 5, 4, 4, 2, 1, 4, 4, 3, 3, 2, 2, 1)
order(x)
But it returns numbers which are different:
## [1] 10 12 13 14 21 28 6 7 20 26 27 4 11 24 25 18 19 22 23 15 16 17 5 3 8 9 1 2
order function returns permutation, not sorted vector:
http://stat.ethz.ch/R-manual/R-patched/library/base/html/order.html
> x <- c (3, 2, 4, 1)
> order(x)
[1] 4 2 1 3
The result (4 2 1 3) means that the smallest item is the 4th (that's 1), the second smallest is the 2nd (2)... and the biggest is the 3d item (which is 4)
if you want to sort the vector, use sort function:
> sort(x)
[1] 1 2 3 4
To sort in decreasing order specify decreasing parameter:
> sort(x, decreasing = TRUE)
[1] 4 3 2 1
order(x) returns indices of the elements of x in increasing order. You'll note that the smallest element of x is in 10th position in x, the second smallest (actually just as small) is at position 12 and so on.
to get x in decreasing order you can either use
sort(x, decreasing=TRUE)
or use order as an index:
x[order(-x)]
(why -x? Because order returns indices in increasing order. by flipping the numbers around zero you get the indices in decreasing order)

sapply 2 vectors

Let's say I have 2 lists
divisor = c(0, 1, 1, 7, 7, 8, 8, 8, 9 )
remainder = c(99, 0, 1, 1, 99, 0, 1, 99, 0)
I want a divisor element to be element + 1 if its corresponding remainder is NOT 0.
The final answer should look like:
updated.divisor = (1, 1, 2, 8, 8, 8, 9, 9, 9)
How would I do this using sapply?
So far I have
sapply(remainder, function(x) {
if x != 0{
#divisor = divisor + 1
}
else{
#divisor = divisor + 0
}
}
P.S. I could probably use a nested loop but I want to be able to do this using sapply.
You don't need a loop:
divisor + (remainder!=0)
[1] 1 1 2 8 8 8 9 9 9
This is one of the most fundamental principles of R: all basic operations (and many functions) accept vectors as input and perform the operation on all elements of that vector at the same time.
To your comment: If you wanted an apply type solution you would use mapply because it allows you to process two arguments "alongside each other":
mapply( function(x,y) {x + !(y==0)}, x=divisor, y=remainder)
#[1] 1 1 2 8 8 8 9 9 9
An ifelse solution would make sense, too:
ifelse(remainder !=0, divisor+1, divisor)
#[1] 1 1 2 8 8 8 9 9 9

Resources