我不知道使用dcast()是否正确,但我想重塑以下data.frame:
df <- data.frame(x=c("p1","p1","p2"),y=c("a","b","a"),z=c(14,14,16))
df
x y z
1 p1 a 14
2 p1 b 14
3 p2 a 16所以看起来就像这个:
df2 <- data.frame(x=c("p1","p2"),a=c(1,1),b=c(1,0),z=c(14,16))
x a b z
1 p1 1 1 14
2 p2 1 0 16应该破坏df中的变量df,以便它的元素是新变量,每个虚拟编码变量。所有其他变量(在本例中仅为z)对于每个人(p1、p2等)是相等的。特定人p具有不同值的唯一变量是y。
我之所以需要这样做,是因为我需要通过变量x将此数据集与其他数据集合并。问题是,它需要每人一行(p1、p2等)。
发布于 2013-08-08 00:00:33
这几乎是一个previous question的复制,我在那里使用的相同的基本答案再次起作用。也不需要任何外部包。
aggregate(model.matrix(~ y - 1, data=df),df[c("x","z")],max)
x z ya yb
1 p1 14 1 1
2 p2 16 1 0为了解释这一点,由于看起来有点奇怪,model.matrix调用在其最基本的位置为data.frame的每一行返回一个二进制指示符变量,如下所示:
ya yb
1 1 0
2 0 1
3 1 0如果通过两个id变量(x和z)对中间结果进行操作,那么实际上是对以下两个变量的初始data.frame进行操作:
x z ya yb
1 p1 14 1 0
2 p1 14 0 1
3 p2 16 1 0因此,如果在max和z的每个组合中取ya和yb的yb值,那么基本上是这样的:
x z ya yb
1 p1 14 1*max* 0
2 p1 14 0 1*max*
--collapse--
x z ya yb
1 p1 14 1 1...and对每个唯一的x/z组合重复这一步骤,以给出最终结果:
x z ya yb
1 p1 14 1 1
2 p2 16 1 0把它推广到更多的专栏有些疯狂,但这是可以做到的,这要归功于this question,例如:
df <- data.frame(x=c("p1","p1","p2"),y=c("a","b","a"),z=c("14","15","16"))
intm <- model.matrix(~ y + z - 1, data=df,
contrasts.arg = sapply(df[2:3], contrasts, contrasts=FALSE))
aggregate(intm,df[c("x")],max)
x ya yb z14 z15 z16
1 p1 1 1 1 1 0
2 p2 1 0 0 0 1发布于 2013-08-07 20:52:21
以下的工作,但似乎繁琐。
df2 <- df
df2$y <- as.numeric(y)
df$y2 <- as.numeric(df$y)
df2 <- dcast(df, x+z~y, value.var="y2")
df2
x z a b
1 p1 14 1 2
2 p2 16 1 NA发布于 2013-08-07 23:17:48
我不确定您需要做什么,但是如果您需要一种自动化的方法,我编写了一个小函数,它可能会有帮助:
第一次运行dcast:
new = dcast(df, x+z~y, value.var="y")加载到您的R环境:
# args to be passed:
# df is your dataframe
# cols is a list of format c("colname1", "colname2", ... , "colnameN")
binarizeCols = function(df, cols){
for(i in cols){
column = which(colnames(df) == i)
truthRow = is.na(df[,column])
for(j in 1:length(truthRow)){
if(truthRow[j] == FALSE){
df[j,column] = 1
}else{
df[j,column] = 0
}
}
}
return(df)
}然后跑:
new = binarizeCols(new, c("a", "b"))你得到的是:
x z a b
1 p1 14 1 1
2 p2 16 1 0不像使用_apply()那么快,但是没有硬编码,您可以输入任何你想要的名字(也许你想在中间跳过一个?)而且您也不会创建df的新实例。注意:我使用"=“而不是"<-”,因为我认为它正在逐步淘汰,但是如果需要的话可以替换它们。
https://stackoverflow.com/questions/18113443
复制相似问题