I tried to create a table with three variables. Now I want to run a Chi-square on both of the outputs. How do I run a Chi-square on the output , , = 1 and again on output , , = 2?
> emphasis<-table(Pilot$emphasis.GI, Pilot$emphasis.race, Pilot$required.learning)
> emphasis
, , = 1
2 3 4
2 11 5 0
3 2 8 0
4 0 0 0
, , = 2
2 3 4
2 0 0 0
3 0 2 0
4 0 0 1
It is a 3D array. We can use apply with MARGIN = 3 and apply the test
apply(emphasis, 3, chisq.test)
Or use a for loop
out <- vector('list', dim(emphasis)[3])
for(i in seq_along(out)) out[[i]] <- chisq.test(emphasis[,, i])
You can try asplit over the third dimension and run chisq.test with Map
Map(chisq.test,asplit(emphasis, 3))
Related
I am struggling to create list of tables (object = table, not data.frame) by loop in R.
Structure of my data is also a little bit complicated - sometimes the table function do not give 2x2 table - how to fill tables with incomplete dimensions to 2x2 automatically?
Sample data (in real dataset much much larger...)
my.data <- data.frame(y.var = c(0,1,0,1,1,1,0,1,1,0),
sex = rep(c("male","female"), times = 5),
apple = c(0,1,1,0,0,0,1,0,0,0),
orange = c(1,0,1,1,0,1,1,1,0,0),
ananas = c(0,0,0,0,0,0,0,0,0,0))
# y.var sex apple orange ananas
# 1 0 male 0 1 0
# 2 1 female 1 0 0
# 3 0 male 1 1 1
Look into creating tables - for apple I have nice 2x2 tables
table(my.data$y.var, my.data$apple)
# 0 1
# 0 2 2
# 1 5 1 .... Ok, nice 2x2 table.
table(my.data$y.var, my.data$apple, my.data$sex)
# , , = female
# 0 1
# 0 1 0
# 1 3 1
# , , = male
# 0 1
# 0 1 2
# 1 2 0 .... Ok, nice 2x2 table.
However for ananas I have only 2x1 tables
table(my.data$y.var, my.data$ananas)
# 0 # 0 1
# 0 4 # 0 4 0
# 1 6 .... NOT Ok! I need 2x2 table like this: # 1 6 0
table(my.data$y.var, my.data$ananas, my.data$sex)
# , , = female
# 0 # 0 1
# 0 1 # 0 1 0
# 1 4 .... NOT Ok! I need 2x2 table like this: # 1 4 0
# , , = male
# 0 # 0 1
# 0 3 # 0 3 0
# 1 2 .... NOT Ok! I need 2x2 table like this: # 1 2 0
I can do list manually like this, however this is not very practical.
my.list <- list(table(my.data$y.var, my.data$apple),
table(my.data$y.var, my.data$apple, my.data$sex),
table(my.data$y.var, my.data$orange),
table(my.data$y.var, my.data$orange, my.data$sex),
table(my.data$y.var, my.data$ananas),
table(my.data$y.var, my.data$ananas, my.data$sex))
How to do self-correcting-table-dimensions-loop? Necessary for following analyses...
We can use lapply to loop over the list of columns after converting the columns of interest to have the same levels with factor and then do a table and keep the output in the list
my.data[-2] <- lapply(my.data[-2], factor, levels = 0:1)
lst1 <- lapply(my.data[3:5], function(x) table(my.data$y.var, x))
I'm trying to create variables to use, for each variable it's called,
M000
M001
M002
M003
Example
c.n_vars <- nrow(comb)
for (i in 1:c.n_vars)
{
paste("M",comb[i,1],comb[i,2],comb[i,3]) = Arima(y,order=c(arima[1,1],arima[2,1],arima[3,1]),seasonal=list(order=c(comb[i,1],comb[i,2],comb[i,3]),period=12))
}
where comb is all combinations
a <- c(0,1,2,3,4)
b <- c(0,1,2,3,4)
c <- c(0,1,2,3,4)
comb <- expand.grid(a, b,c)
row parameter1 parameter2 parameter3
1 0 0 0
2 1 0 0
3 2 0 0
4 3 0 0
5 4 0 0
6 0 1 0
7 1 1 0
8 2 1 0
9 3 1 0
10 4 1 0
11 0 2 0
12 1 2 0
13 2 2 0
14 3 2 0
15 4 2 0
and arima is
arima <- data.frame(c(2,1,4))
row parameters
1 2
2 1
3 4
i am trying to create
c.n_vars <- nrow(comb)
for (i in 1:c.n_vars)
{
paste("M",comb[i,1],comb[i,2],comb[i,3]) = Arima(y,order=c(arima[1,1],arima[2,1],arima[3,1]),seasonal=list(order=c(comb[i,1],comb[i,2],comb[i,3]),period=12))
}
this code must return
for i = 1
M000 = arima model saved in that variable
for i = 2
M100 = arima model saved in that variable
for i = 3
M200 = arima model saved in that variable
.
.
.
.
.
for i = 15
M420 = arima model saved in that variable
and the following error appears
Error in paste("M", comb[i, 1], comb[i, 2], comb[i, 3]) = Arima(y, order = c(arima[1, :
assignment target expands an object out of language
I need that each iteration of the variable 'i' be saved in a different variable
Is there any solution? or another way to do it
Your sample code is still incomplete. I was not able to run it. For example y is missing.
As Base_R_Best_R pointed out, you cannot use paste to create variables like that. You can use the following pattern instead. Also note that I replaced paste() with paste0() to avoid spaces in the names:
result = list()
for (i in 1:c.n_vars)
{
result[[paste0("M",comb[i,1],comb[i,2],comb[i,3])]] = Arima(y,order=c(arima[1,1],arima[2,1],arima[3,1]),seasonal=list(order=c(comb[i,1],comb[i,2],comb[i,3]),period=12))
}
Access your variables like this:
result$M100
In this simple example, I'm trying to see the number of students sharing the same class. This is what I came up with but I'd like to know how to do this without loops, and potentially how to show which students (or positions P1, P2, P3, P4) share a class together. If these were numbers I think it would be done simply through a correlation matrix, but given the categorical nature I'm not sure how to go about it other than this.
DF <- (data.frame(row.names= c("ClassA", "ClassB","ClassC","ClassD","ClassE","ClassF"),
P1=c("John","John","Dave","Patrick","Steve","John"),
P2=c("Jim","Jim","Robert","Matt","Jim","Ben"),
P3=c("Marty","Mike","Stu","Geoff","Mike","Leif"),
P4=c("Mark","Mark","Tim","Moby","Chester","Larry")))
DFtally <- matrix(ncol=6, nrow=6)
for (i in 1:dim(DF)[1]) {
for (j in 1:dim(DF)[1]) {
DFtally[i,j] <- length(intersect(t(DF[i,]),t(DF[j,])))
}
}
library(plotly)
p <- plot_ly(z = DFtally, type = "heatmap")
p
Try this:
DF2 <- split(as.matrix(DF), 1:nrow(DF))
DF2 <- crossprod(table(stack(DF2)))
DF2
# ind
# ind 1 2 3 4 5 6
# 1 4 3 0 0 1 1
# 2 3 4 0 0 2 1
# 3 0 0 4 0 0 0
# 4 0 0 0 4 0 0
# 5 1 2 0 0 4 0
# 6 1 1 0 0 0 4
I am having problem with changing a specific column in a matrix and giving it a new name. Let's say
A =
2 2 2
2 2 2
2 2 2
I would like to make 3 matrix which are
A1 =
0 2 2
0 2 2
0 2 2
A2 =
2 0 2
2 0 2
2 0 2 and so on.
I tried a for loop with A[,i] <- 0 but this changes all the elements in A to 0.
I have tried A - A[,i] but this all the column of A are being subtracted by the vector A[,i].... Please help me!
Building on #lmo's comment you can do:
a <- matrix(2, 3, 3)
x <- lapply(seq_len(ncol(a)), function(i) {a[, i] <- 0; a})
names(x) <- paste("a",1:length(x), sep = "")
list2env(x, envir=.GlobalEnv)
I've got a column in my dataset that contains a collection of 0,1 and 2. The 2's are a weird leftover from some previous transformation, and I need to convert them to 1. I've written a simple loop to do this
for (i in my.cl.accept$enroll){
if (i==2){
i=1
}
}
however, this doesn't change the actual contents of the dataframe. ifelse() doesn't work, because I don't need to change the other digits at all; just the number 2.
I've been using R a little more after coming from python, what simple thing am I misunderstanding here?
Lets generate a sample set:
set.seed(10)
DF <- data.frame(
a=1:10,
b=sample(0:2,10,rep=T))
DF
Now, replace every entry corresponding to 2 with 1:
DF$b[DF$b==2] <- 1
DF
Note: This is a vectorized method, and will always work faster than loop iterations.
Dunno whether this is what you want?
> A<- 1:10
> B<- c(rep(0,5), rep(1,3), rep(2,2))
> data <- data.frame(A,B)
> data
A B
1 1 0
2 2 0
3 3 0
4 4 0
5 5 0
6 6 1
7 7 1
8 8 1
9 9 2
10 10 2
> data[data$B==2,]$B <- 1
> data
A B
1 1 0
2 2 0
3 3 0
4 4 0
5 5 0
6 6 1
7 7 1
8 8 1
9 9 1
10 10 1
Are you sure you're using ifelse correctly? It actually does allow you to only change one value to another. Here's an example:
> x <- sample(c(0, 1, 2), 10, TRUE)
> x
## [1] 2 1 1 0 2 2 0 0 2 1
> ifelse(x == 2, 1, x)
## [1] 1 1 1 0 1 1 0 0 1 1
For future reference, your good old-fashioned for loop should go something like this...
for (i in 1:length(my.cl.accept$enroll)){
if (my.cl.accept$enroll[i] == 2){
my.cl.accept$enroll[i] <- 1
} else {
my.cl.accept$enroll[i]
}
}