This question already has an answer here:
Multiply each element in a vector by itself to create a matrix
(1 answer)
Closed 8 years ago.
I have this matrix
m<- matrix(c(0:13),nrow=2,ncol=7)
colnames(m)<-c("0","1","2","3","4","5","6")
rownames(m)<-c("A","B")
0 1 2 3 4 5 6
A 0 2 4 6 8 10 12
B 1 3 5 7 9 11 13
and I want to multiply each observation in row one by each observation in row two. So I would have something that looks like this
0 1 2 3 4 5 6
0 NA NA NA NA NA NA NA
1 NA NA NA NA NA NA NA
2 NA NA NA NA NA NA NA
3 NA NA NA NA NA NA NA
4 NA NA NA NA NA NA NA
5 NA NA NA NA NA NA NA
6 NA NA NA NA NA NA NA
Try
outer(m[1,], m[2,], FUN='*')
or
as.matrix(m[1,])%*% m[2,]
Related
I have generated random data like this.
data <- replicate(10,sample(0:9,10,rep=FALSE))
ind <- which(data %in% sample(data, 5))
#now replace those indices in data with NA
data[ind]<-NA
#here is our vector with 15 random NAs
data = as.data.frame(data)
rownames(data) = 1:10
colnames(data) = 1:10
data
which results in a data frame like this. How can I reorder the entry value such that if the entry is numeric, then the value will be placed in a (row number - 1), and NA will be put in any rows where there is no value matching the (row number -1). The data I want, for example, the first column, should look like this
.
How can I do this? I have no clue at all. We can order decreasing or increasing and put NA in the last order, but that is not what I want.
You can make a helper function to assign values to indices at (values + 1), then apply the function over all columns:
fx <- function(x) {
vals <- x[!is.na(x)]
pos <- vals + 1
out <- rep(NA, length(x))
out[pos] <- vals
out
}
as.data.frame(sapply(data, fx))
1 2 3 4 5 6 7 8 9 10
1 NA 0 NA 0 0 0 0 NA 0 0
2 NA NA NA 1 1 NA NA NA NA NA
3 2 NA 2 2 NA NA NA NA 2 NA
4 3 NA 3 3 NA NA 3 NA 3 3
5 4 4 4 4 NA 4 NA 4 4 NA
6 5 5 NA 5 NA NA 5 5 5 NA
7 NA 6 6 NA 6 NA NA 6 NA NA
8 7 NA 7 7 NA 7 7 NA NA 7
9 NA NA NA NA 8 8 8 8 8 8
10 9 9 NA NA 9 NA NA 9 NA 9
Starting data:
set.seed(13)
data <- replicate(10, sample(
c(0:9, rep(NA, 10)),
10,
replace = FALSE
))
data <- as.data.frame(data)
colnames(data) <- 1:10
data
1 2 3 4 5 6 7 8 9 10
1 2 NA NA 2 NA NA 0 NA 3 7
2 4 NA NA 4 NA NA NA NA 2 9
3 9 9 NA 3 9 4 NA 6 4 0
4 NA NA NA 1 6 NA NA 4 NA NA
5 5 6 3 0 NA NA 5 8 8 NA
6 NA NA 7 NA NA NA 7 NA 5 3
7 3 4 6 NA 1 0 NA 5 NA NA
8 NA NA NA 7 0 7 NA NA 0 NA
9 NA 0 4 NA 8 8 8 9 NA 8
10 7 5 2 5 NA NA 3 NA NA NA
This question already has answers here:
Add empty columns to a dataframe with specified names from a vector
(6 answers)
Closed 4 years ago.
I have some data:
df = data.frame(matrix(rnorm(20), nrow=10))
X1 X2
1 1.17596402 0.06138821
2 -1.76439330 1.03674803
3 -0.39069424 0.61616793
4 0.68375346 0.27435354
5 0.27426476 -1.71226109
6 -0.06153577 1.14514453
7 -0.37067621 -0.61243104
8 1.11107852 0.47788971
9 -1.73036658 0.31545148
10 -1.83155718 -0.14433432
I want to add new variables to it for every element in a list, which changes:
list = c("a","b","c")
The result should be:
X1 X2 a b c
1 1.17596402 0.06138821 NA NA NA
2 -1.76439330 1.03674803 NA NA NA
3 -0.39069424 0.61616793 NA NA NA
4 0.68375346 0.27435354 NA NA NA
5 0.27426476 -1.71226109 NA NA NA
6 -0.06153577 1.14514453 NA NA NA
7 -0.37067621 -0.61243104 NA NA NA
8 1.11107852 0.47788971 NA NA NA
9 -1.73036658 0.31545148 NA NA NA
10 -1.83155718 -0.14433432 NA NA NA
I can do this using suggestions below:
df[list] <- NA
But now, I want to search every row for the variable name as a value and flag if it contains that value. For example:
X1 X2 a b c
1 a b 1 1 0
2 a c 1 0 1
So the code would search for "a" in all columns and flag if any column contains "a". How do I do this?
You can use
df[list] <- NA
The result:
X1 X2 a b c
1 -2.07205164 -0.93585363 NA NA NA
2 1.11014587 0.23468072 NA NA NA
3 -1.17909665 0.04741478 NA NA NA
4 0.23955056 1.02029880 NA NA NA
5 -0.79212220 -1.13485661 NA NA NA
6 -0.57571547 0.33069641 NA NA NA
7 -0.70063920 -0.17251563 NA NA NA
8 1.90625189 0.30277177 NA NA NA
9 0.09029121 -0.72104778 NA NA NA
10 -1.36324313 -1.48041873 NA NA NA
If you want to add only the variables that are not present in df, you can use:
df[list[!list %in% names(df)]] <- NA
Say I have a data frame as follows (in reality this is multiple data frames bound):
data.frame(
position = c(3,4,7,12,NA,NA,NA,NA,NA,NA,NA,NA),
colb = c(1,3,8,2,NA,NA,NA,NA,NA,NA,NA,NA),
colc = c(4,6,9,5,NA,NA,NA,NA,NA,NA,NA,NA),
position = c(2,7,8,10,11,12,15,16,19,21,24,26),
colb = c(1,3,8),
colc = c(4,6,9)
)
(Sorry, gets flagged if I post the data format myself.)
How can I transform this so I have a unified system of indicating a 'position'? ie one of the two formats below.
A single column scale:
position colb colc colb.1 colc.1
1 NA NA NA NA
2 NA NA 1 4
3 1 4 NA NA
4 3 6 NA NA
5 NA NA NA NA
6 NA NA NA NA
7 8 9 3 6
8 NA NA 8 9
9 NA NA NA NA
10 NA NA 1 4
11 NA NA 3 6
12 2 5 8 9
13 NA NA NA NA
14 NA NA NA NA
15 NA NA 1 4
16 NA NA 3 6
17 NA NA NA NA
18 NA NA NA NA
19 NA NA 8 9
20 NA NA NA NA
21 NA NA 1 4
22 NA NA NA NA
23 NA NA NA NA
24 NA NA 3 6
25 NA NA NA NA
26 NA NA 8 9
Or with separate columns, but 'matching':
position colb colc position.1 colb.1 colc.1
NA NA NA NA NA NA
NA NA NA 2 3 6
3 1 4 NA NA NA
4 3 6 NA NA NA
NA NA NA NA NA NA
NA NA NA NA NA NA
7 8 9 7 1 4
NA NA NA 8 3 6
NA NA NA NA NA NA
NA NA NA 10 1 4
NA NA NA 11 3 6
12 2 5 12 8 9
NA NA NA NA NA NA
NA NA NA NA NA NA
NA NA NA 15 8 9
NA NA NA 16 1 4
NA NA NA NA NA NA
NA NA NA NA NA NA
NA NA NA 19 1 4
NA NA NA NA NA NA
NA NA NA 21 8 9
NA NA NA NA NA NA
NA NA NA NA NA NA
NA NA NA 24 8 9
NA NA NA NA NA NA
NA NA NA 26 8 9
Any help is appreciated. Thanks.
If df contains the dataframe
df <- data.frame(
position = c(3,4,7,12,NA,NA,NA,NA,NA,NA,NA,NA),
colb = c(1,3,8,2,NA,NA,NA,NA,NA,NA,NA,NA),
colc = c(4,6,9,5,NA,NA,NA,NA,NA,NA,NA,NA),
position = c(2,7,8,10,11,12,15,16,19,21,24,26),
colb = c(1,3,8),
colc = c(4,6,9)
)
df1 <- df[,1:3]
df2 <- df[,4:6]
names(df2) <- c("position", "colb", "colc")
df_out <- rbind(df1, df2)
df_out <- df_out[!is.na(df_out$position),]
df_out <- df_out[order(df_out$position),]
df_out
This question already has answers here:
All combinations of all sizes?
(2 answers)
Unordered combinations of all lengths
(3 answers)
Closed 4 years ago.
I would like to build a dataframe that lists all possible combinations of 6 numbers.
I realised that I can use combn(), but with only one value for m. With a bit of playing around I got the desired result by going through step-by-step with the following code -
combi1 <- data.frame(c(1:6))
colnames(combi1) <- 'X1'
combi2 <- data.frame(t(combn(c(1:6), 2)))
combi3 <- data.frame(t(combn(c(1:6), 3)))
combi4 <- data.frame(t(combn(c(1:6), 4)))
combi5 <- data.frame(t(combn(c(1:6), 5)))
combi6 <- data.frame(t(combn(c(1:6), 6)))
Combi <- rbind.fill(combi1, combi2, combi3, combi4, combi5, combi6)
I had to transpose each of the DFs to get them in the right shape.
My problem is that this seems to be quite an in-efficient method. Maybe a bit simplistic. I thought there must surely be some quicker way to code this, but haven't found any solution online that gives me what I'd like.
Possibly build it into a function or a loop somehow? I'm fairly new to R though and haven't had a great deal of practice writing functions.
Is it what you want ?
combis <- vector("list", 6)
combi1 <- data.frame(c(1:6))
colnames(combi1) <- 'X1'
combis[[1]] <- combi1
combis[2:6] <- lapply(2:6, function(n) data.frame(t(combn(c(1:6), n))))
do.call(plyr::rbind.fill, combis)
Result:
X1 X2 X3 X4 X5 X6
1 1 NA NA NA NA NA
2 2 NA NA NA NA NA
3 3 NA NA NA NA NA
4 4 NA NA NA NA NA
5 5 NA NA NA NA NA
6 6 NA NA NA NA NA
7 1 2 NA NA NA NA
8 1 3 NA NA NA NA
9 1 4 NA NA NA NA
10 1 5 NA NA NA NA
11 1 6 NA NA NA NA
12 2 3 NA NA NA NA
13 2 4 NA NA NA NA
14 2 5 NA NA NA NA
15 2 6 NA NA NA NA
16 3 4 NA NA NA NA
17 3 5 NA NA NA NA
18 3 6 NA NA NA NA
19 4 5 NA NA NA NA
20 4 6 NA NA NA NA
21 5 6 NA NA NA NA
22 1 2 3 NA NA NA
23 1 2 4 NA NA NA
24 1 2 5 NA NA NA
25 1 2 6 NA NA NA
26 1 3 4 NA NA NA
27 1 3 5 NA NA NA
28 1 3 6 NA NA NA
29 1 4 5 NA NA NA
30 1 4 6 NA NA NA
31 1 5 6 NA NA NA
32 2 3 4 NA NA NA
33 2 3 5 NA NA NA
34 2 3 6 NA NA NA
35 2 4 5 NA NA NA
36 2 4 6 NA NA NA
37 2 5 6 NA NA NA
38 3 4 5 NA NA NA
39 3 4 6 NA NA NA
40 3 5 6 NA NA NA
41 4 5 6 NA NA NA
42 1 2 3 4 NA NA
43 1 2 3 5 NA NA
44 1 2 3 6 NA NA
45 1 2 4 5 NA NA
46 1 2 4 6 NA NA
47 1 2 5 6 NA NA
48 1 3 4 5 NA NA
49 1 3 4 6 NA NA
50 1 3 5 6 NA NA
51 1 4 5 6 NA NA
52 2 3 4 5 NA NA
53 2 3 4 6 NA NA
54 2 3 5 6 NA NA
55 2 4 5 6 NA NA
56 3 4 5 6 NA NA
57 1 2 3 4 5 NA
58 1 2 3 4 6 NA
59 1 2 3 5 6 NA
60 1 2 4 5 6 NA
61 1 3 4 5 6 NA
62 2 3 4 5 6 NA
63 1 2 3 4 5 6
I need some help with subset/filter of data.frame. Below is the code for my random dataset.
A <- c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4)
B <- c(3,3,3,3,4,4,4,4,1,1,1,1,2,2,2,2)
C <- c(1,1,1,1,3,3,3,3,2,2,2,2,4,4,4,4)
Fakey <- data.frame(A, B, C)
Filter_Fakey <- subset(Fakey, (Fakey>1 & Fakey<4))
That last line of coode results in the following:
> Filter_Fakey
A B C
5 2 4 3
6 2 4 3
7 2 4 3
8 2 4 3
9 3 1 2
10 3 1 2
11 3 1 2
12 3 1 2
NA NA NA NA
NA.1 NA NA NA
NA.2 NA NA NA
NA.3 NA NA NA
NA.4 NA NA NA
NA.5 NA NA NA
NA.6 NA NA NA
NA.7 NA NA NA
NA.8 NA NA NA
NA.9 NA NA NA
NA.10 NA NA NA
NA.11 NA NA NA
NA.12 NA NA NA
NA.13 NA NA NA
NA.14 NA NA NA
NA.15 NA NA NA
But What I really want is this,
> Filter_Fakey
A B C
5 2 3 3
6 2 3 3
7 2 3 3
8 2 3 3
9 3 2 2
10 3 2 2
11 3 2 2
12 3 2 2
NA NA NA NA
NA.1 NA NA NA
NA.2 NA NA NA
NA.3 NA NA NA
NA.4 NA NA NA
NA.5 NA NA NA
NA.6 NA NA NA
NA.7 NA NA NA
NA.8 NA NA NA
NA.9 NA NA NA
NA.10 NA NA NA
NA.11 NA NA NA
NA.12 NA NA NA
NA.13 NA NA NA
NA.14 NA NA NA
NA.15 NA NA NA
I've tried subset(), subset(with a negation condition), filter{dplyr}, and the different bracket notations ('[' and '[['). Thanks for helping me out.
Use lapply to loop through columns of the data frame, and set values out of conditions to be NA if that is what you are after. Use order(is.na(...)) to arrange NA values to the last positions:
do.call(cbind, lapply(Fakey, function(col) {
col[col <= 1 | col >= 4] <- NA; col[order(is.na(col))]
}))
A B C
1 2 3 3
2 2 3 3
3 2 3 3
4 2 3 3
5 3 2 2
6 3 2 2
7 3 2 2
8 3 2 2
9 NA NA NA
10 NA NA NA
11 NA NA NA
12 NA NA NA
13 NA NA NA
14 NA NA NA
15 NA NA NA
16 NA NA NA
Another option is using length<- to pad NA at the end after subsetting each of the columns using the logical condition.
data.frame(lapply(Fakey, function(x) `length<-`(x[x > 1 & x <4], nrow(Fakey))))
# A B C
#1 2 3 3
#2 2 3 3
#3 2 3 3
#4 2 3 3
#5 3 2 2
#6 3 2 2
#7 3 2 2
#8 3 2 2
#9 NA NA NA
#10 NA NA NA
#11 NA NA NA
#12 NA NA NA
#13 NA NA NA
#14 NA NA NA
#15 NA NA NA
#16 NA NA NA