R 每年的虚拟变量

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

如果我有下面的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)

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换行。