如果我有以下data.frame,我将如何为每年创建一个虚拟变量并将其附加到DF,这样就会有额外的列year2010和year2011。我有一个相当大的数据集,有很多不同的年份,我不想使用ifelse 50次。 ddply?
由于
DF <- read.table(text=" year id var ans
2010 1 1 1
2010 2 0 0
2010 1 0 1
2010 1 0 1
2011 2 1 1
2011 2 0 1
2011 1 0 0
2011 1 0 0", header=TRUE)
期望的输出:
year id var ans year_2010 year_2011
1 2010 1 1 1 1 0
2 2010 2 0 0 1 0
3 2010 1 0 1 1 0
4 2010 1 0 1 1 0
5 2011 2 1 1 0 1
6 2011 2 0 1 0 1
7 2011 1 0 0 0 1
8 2011 1 0 0 0 1
1
答案 0 :(得分:4)
这是我最喜欢的用于从分类变量创建虚拟变量的代码。
唯一的区别是这段代码产生K-1
虚拟变量以避免共线:
x = as.factor( rep(1:6,each=4) );
model.matrix(~x)[,-1]
用您的数据集中的年份替换x
。
答案 1 :(得分:4)
只需使用table
,就像这样:
cbind(DF, as.data.frame.matrix(table(sequence(nrow(DF)), DF$year)))
year id var ans 2010 2011
1 2010 1 1 1 1 0
2 2010 2 0 0 1 0
3 2010 1 0 1 1 0
4 2010 1 0 1 1 0
5 2011 2 1 1 0 1
6 2011 2 0 1 0 1
7 2011 1 0 0 0 1
8 2011 1 0 0 0 1
您还应该能够做到这样的事情:
library(data.table)
cbind(DF,
dcast.data.table(as.data.table(DF, keep.rownames = TRUE),
rn ~ year, value.var = "id", fun.aggregate = length))
# year id var ans rn 2010 2011
# 1 2010 1 1 1 1 1 0
# 2 2010 2 0 0 2 1 0
# 3 2010 1 0 1 3 1 0
# 4 2010 1 0 1 4 1 0
# 5 2011 2 1 1 5 0 1
# 6 2011 2 0 1 6 0 1
# 7 2011 1 0 0 7 0 1
# 8 2011 1 0 0 8 0 1
如果您希望姓名为&#34; year_2010&#34;等等,我想解决方法是做这样的事情:
dcast.data.table(as.data.table(DF, keep.rownames = TRUE)[, yr := "year"],
rn ~ yr + year, value.var = "id", fun.aggregate = length)
您也可以随时编写自己的功能。在这里我鞭打了一个应该合理有效的人:
dummyCreator <- function(invec, prefix = NULL) {
L <- length(invec)
ColNames <- sort(unique(invec))
M <- matrix(0L, ncol = length(ColNames), nrow = L,
dimnames = list(NULL, ColNames))
M[cbind(seq_len(L), match(invec, ColNames))] <- 1L
if (!is.null(prefix)) colnames(M) <- paste(prefix, colnames(M), sep = "_")
M
}
dummyCreator(DF$year, prefix = "year")
# year_2010 year_2011
# [1,] 1 0
# [2,] 1 0
# [3,] 1 0
# [4,] 1 0
# [5,] 0 1
# [6,] 0 1
# [7,] 0 1
# [8,] 0 1
只需使用上述cbind
即可获得您期望的输出。
答案 2 :(得分:2)
也许这个?
library(tidyr)
DF$row <- 1:nrow(DF) # to make each row unique
DF$dummy <- 1
newdf <- spread(DF, year, dummy, fill = 0)
答案 3 :(得分:2)
for(i in unique(DF$year)) {
DF[paste('year',i,sep="")]=DF$year==i
}
答案 4 :(得分:2)
正如Andrey Shabalin所说,你想要model.matrix
。首先,您需要将year
列转换为一个因素。要准确获得所需内容,您需要在caret
包中使用contr.ltfr
contr.treatment
的修改版本。
在下面的公式中,0
表示不使用截距,.
表示数据框中的所有列。
DF$year <- factor(DF$year)
model.matrix(
~ 0 + .,
DF,
contrasts.arg = list(year = "contr.ltfr")
)