r行范围的条件替换

时间:2010-09-24 12:20:09

标签: r

我正在尝试为规范相关性分析设置matrixdata.frame。原始数据集有一列指定x条件之一和后续解释变量列。我需要设置一个数组,为每个条件“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 个答案:

答案 0 :(得分:3)

如果您将cond编码为一个因素,则可以通过model.matrix让R进行所需的扩展。唯一的复杂因素是,要获得您选择的编码(虚拟变量编码或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中级别数的变化/增加,这应自动缩放。

HTH

答案 1 :(得分:2)

另一种方法是在重塑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

答案 2 :(得分:1)

使用model.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)))

答案 3 :(得分:0)

再一次,开源的伟大典范!非常感谢你的帮助。最初的解决方案似乎最适合我。如果其他人可能感兴趣,这是我用我的(非常大的)数据集实现的方法:

 # 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")