г рядная условная замена - PullRequest
1 голос
/ 24 сентября 2010

Друзья

Я пытаюсь настроить matrix или data.frame для канонического корреляционного анализа.Исходный набор данных имеет столбец, обозначающий одно из условий x и последующие столбцы объясняющих переменных.Мне нужно настроить массив, который устанавливает переменную индикатора для каждого условия «х».например.Столбцы в df:

ID cond task1 taskN  
A, x, 12, 14  
B, x, 13, 17  
C, y, 11, 10  
D, z, 10, 13  

здесь "cond" может быть x, y, z, ... (может варьироваться, поэтому я не знаю, сколько).Для этого нужно перейти к:

ID, x, y, z, task1, taskN  
A, 1, 0, 0, 12, 14  
B, 1, 0, 0, 13, 17  
C, 0, 1, 0, 11, 10  
D, 0, 0, 1, 10, 13  

Итак, я могу настроить индикаторы в массиве

iv<-as.data.frame(array(,c(nrow(df),length(levels(cond)))))  

, а затем cbind это в df, но я не могу понятьузнать, как перейти в массив и установить соответствующий индикатор в «1», а остальные в «0».

Есть предложения?

Спасибо

Джон

Ответы [ 4 ]

3 голосов
/ 24 сентября 2010

Если вы в качестве фактора наберете cond, вы можете получить R, чтобы выполнить расширение, которое вы хотите, с помощью model.matrix. Единственное осложнение состоит в том, что для получения выбранной вами кодировки (кодирование фиктивных переменных или контрастов суммы в R) нам нужно изменить стандартные контрасты, используемые кодом формулы модели R.

## data
dat <- data.frame(ID = LETTERS[1:4], cond = factor(c("x","x","y","z")),
                  task1 = c(12,13,11,10), taskN = c(14,17,10,13))
dat

## We get R to produce the dummy variables for us,
## but your coding needs the contr.sum contrasts
op <- options(contrasts = c("contr.sum","contr.poly"))
dat2 <- data.frame(ID = dat$ID, model.matrix(ID ~ . - 1, data = dat))
## Levels of cond
lev <- with(dat, levels(cond))
## fix-up the names
names(dat2)[2:(1+length(lev))] <- lev
dat2

## reset contrasts
options(op)

Это дает нам:

> dat2
  ID x y z task1 taskN
1  A 1 0 0    12    14
2  B 1 0 0    13    17
3  C 0 1 0    11    10
4  D 0 0 1    10    13

Это масштабируется автоматически при изменении / увеличении количества уровней в cond.

НТН

2 голосов
/ 24 сентября 2010

Другой альтернативой является использование cast в форме package:

library(reshape)
l <- length(levels(dat$cond))
dat2 <- merge(cast(dat,ID~cond),dat)[,c(1:(l+1),(l+3):(ncol(dat)+l))]
dat2[,2:(1+l)] <- !is.na(dat2[,2:(1+l)])

Это дает вам логические значения, а не 0 и 1, хотя:

> dat2
  ID     x     y     z task1 taskN
1  A  TRUE FALSE FALSE    12    14
2  B  TRUE FALSE FALSE    13    17
3  C FALSE  TRUE FALSE    11    10
4  D FALSE FALSE  TRUE    10    13
1 голос
/ 24 сентября 2010

Круто использовать модель .matrix для этого. (изменить тоже.) Здесь всегда чему-то учатся. Еще пара идей:

indicator1 <- function(groupStrings) {
  groupFactors <- factor(groupStrings)
  colNames <- levels(groupFactors)
  bits <- matrix(0, nrow=length(groupStrings), ncol=length(colNames))
  bits[matrix(c(1:length(groupStrings),
                unclass(groupFactors)), ncol=2)] <- 1
  setNames(as.data.frame(bits), colNames)
}

indicator2 <- function(groupStrings) {
  colNames <- unique(groupStrings)
  bits <- outer(groupStrings, colNames, "==")
  setNames(as.data.frame(bits * 1), colNames)
}

Используется следующим образом

d <- data.frame(cond=c("a", "a", "b"))
d <- cbind(d, indicator2(as.character(d$cond)))
0 голосов
/ 27 сентября 2010

Опять же, отличный пример величия open-source!Большое спасибо за Вашу помощь.Первоначальное решение, казалось, работало лучше всего для меня.В случае, если кому-то еще может быть интересно, вот как я реализовал это с моим (очень большим) набором данных:

 # Load needed libraries if not already so  
if("packages:sciplot" %in% search()) next else library(moments)  

 # Initialize dataframes. DEFINE THE workspace SUBSET TO ANALYZE HERE  
 df<-stroke  

 # Make any necessary modifications to the df  
 df$TrDif <- df$TrBt-df$TrAt  

 # 0) Set up indicator variables (iv) from the factor you choose.  
 op <- options(contrasts = c("contr.sum","contr.poly"))  
 dat<-subset(df,select=c("newcat"))  
 iv<-data.frame(model.matrix(~.-1,data=dat))  
 names(iv) <- levels(dat$newcat)  
 lbl<-levels(dat$newcat) # need this for plot functions below  

 # Select task variables with n > 1150 to be regressed (THIS CAN PROBABLY BE DONE MORE ELEGANTLY).  
 taskarr<-subset(df,   select=c("B20","B40","FW","Anim","TrAt","TrBt","TrBerr","TrDif","Snod15","tt","GEMS","Clock3","orient","Wlenc","wlfr","wlcr","wlrec","Snod15Rec","GEMSfr"))  

 ## 1) evaluate covariance matrix and extract sub-matrices  
 ## Caution: Covariance samples differ due to missing values.  
 sig <- cov(cbind(iv,taskarr),use="pairwise.complete.obs")  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...