R 每年的虚拟变量
如果我有下面的data.frame,我将如何为每一年创建一个虚拟变量,并将其附加到DF,这样就有了额外的列year2010和year2011。我有一个相当大的数据集,有许多不同的年份,我不想使用ifelse 50次。ddply 谢谢R 每年的虚拟变量,r,R,如果我有下面的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
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)
1以下是我最喜欢的代码,用于从分类变量创建虚拟变量。 唯一的区别是,此代码生成K-1伪变量以避免共线性:
x = as.factor( rep(1:6,each=4) );
model.matrix(~x)[,-1]
用数据集中的年份替换x。以下是我最喜欢的代码,用于从分类变量创建虚拟变量。 唯一的区别是,此代码生成K-1伪变量以避免共线性:
x = as.factor( rep(1:6,each=4) );
model.matrix(~x)[,-1]
用数据集中的年份替换x。可能是这样吗
library(tidyr)
DF$row <- 1:nrow(DF) # to make each row unique
DF$dummy <- 1
newdf <- spread(DF, year, dummy, fill = 0)
也许是这个
library(tidyr)
DF$row <- 1:nrow(DF) # to make each row unique
DF$dummy <- 1
newdf <- spread(DF, year, dummy, fill = 0)
正如安德烈·沙巴林所提到的,你想要。首先,您需要将年份列转换为一个因子。为了得到您想要的,您需要在插入符号包中使用的修改版本 在下面的公式中,0表示不使用截距和。表示数据框中的所有列
DF$year <- factor(DF$year)
model.matrix(
~ 0 + .,
DF,
contrasts.arg = list(year = "contr.ltfr")
)
正如安德烈·沙巴林所提到的,你想要。首先,您需要将年份列转换为一个因子。为了得到您想要的,您需要在插入符号包中使用的修改版本 在下面的公式中,0表示不使用截距和。表示数据框中的所有列
DF$year <- factor(DF$year)
model.matrix(
~ 0 + .,
DF,
contrasts.arg = list(year = "contr.ltfr")
)
只需使用表格,如下所示:
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
dcast.data.table(as.data.table(DF, keep.rownames = TRUE)[, yr := "year"],
rn ~ yr + year, value.var = "id", fun.aggregate = length)
您还应该能够执行以下操作:
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
dcast.data.table(as.data.table(DF, keep.rownames = TRUE)[, yr := "year"],
rn ~ yr + year, value.var = "id", fun.aggregate = length)
如果您希望名称为2010年等等,我想解决方法是这样做:
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
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即可获得预期的输出。只需使用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
dcast.data.table(as.data.table(DF, keep.rownames = TRUE)[, yr := "year"],
rn ~ yr + year, value.var = "id", fun.aggregate = length)
您还应该能够执行以下操作:
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
dcast.data.table(as.data.table(DF, keep.rownames = TRUE)[, yr := "year"],
rn ~ yr + year, value.var = "id", fun.aggregate = length)
如果您希望名称为2010年等等,我想解决方法是这样做:
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
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即可获得您期望的输出。在DF中,您已经有一年了。这是你期待的吗?或者这是DF的一部分?@jazzurro我需要区分年份的虚拟变量列。请使用此示例输入显示您所需的输出。我想知道简单的DF$year=factorDF$year对您来说是否足够,并且根本不需要创建虚拟变量。R中的线性回归将因子变量理解为分类变量。“不起作用”是相当模糊的。不管怎样,祝你好运。在DF,你已经有一年了。这是你期待的吗?或者这是DF的一部分?@jazzurro我需要区分年份的虚拟变量列。请使用此示例输入显示您所需的输出。我想知道简单的DF$year=factorDF$year对您来说是否足够,并且根本不需要创建虚拟变量。R中的线性回归将因子变量理解为分类变量。“不起作用”是相当模糊的。不管怎样,祝你好运。这是可行的,但会将年份列从数据中删除。frame@Amstell没问题:newdf$year=DF$year,但将年份列从数据中删除。frame@Amstell没问题:newdf$year=DF$year。这不起作用,并抛出一个带有维度的错误。在运行code.model.matrix~as.factorDF$year[,-1]之前,不要忘了将as.factor应用于year列。好的,这是可行的,但我仍然需要将其附加到原始数据集以运行回归。Thankscbindf,model.matrix~as.factorDF$year[,-1]这不起作用,并抛出一个维度错误。在运行代码之前,不要忘记将as.factor应用于year列。model.matrix~as.factorDF$year[,-1]好的,这是可行的,但我仍然需要将其附加到原始数据集中以运行回归。谢谢你的回答,谢谢你的回答,但是我目前的数据集中有166个变量,我正在寻找最快的方法来实现这一点,不需要ifelse,也不需要列出我想要保留的所有变量。你不需要粘贴公式,只需将其设置为~。+0.谢谢你的回答,但我当前的数据集中有166个变量,我正在寻找最快的方法来实现这一点,而不需要ifelse并列出我想要保留的所有变量。你不需要粘贴公式,只需将其设置为~。+这是个好主意。现在记笔记。加一这是可行的,但每当我点击Rstudio中的数据时,虚拟变量就不会显示出来。你知道为什么吗?@amsterl,你分配了输出吗?@AnandaMahto是的。在DF@amsterll中,dimDF是否提供了您期望的尺寸?namesDF是否提供了所需的列名?没有更多的细节就有点难说了。这是个好主意。现在记笔记。加一这是可行的,但每当我点击Rstudio中的数据时,虚拟变量就不会显示出来。你知道为什么吗?@Amsterll,
您分配了输出吗?@AnandaMahto是的。在DF@amsterll中,dimDF是否提供了您期望的尺寸?namesDF是否提供了所需的列名?没有更多细节就有点难说了。@amsterl没问题:用as.numeric换行。@amsterl没问题:用as.numeric换行。