【问题标题】:Dummy Variable for each year每年的虚拟变量
【发布时间】:2015-01-24 08:25:55
【问题描述】:

如果我有以下 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

【问题讨论】:

  • 在 DF 中,您已经拥有 year。这是你所期待的吗?或者这是 DF 的一部分?
  • @jazzurro 我需要虚拟变量列来区分年份。
  • 请使用此示例输入显示您想要的输出。
  • 我想知道简单的DF$year = factor(DF$year) 是否足以满足您的需求,并且根本不需要创建虚拟变量。 R 中的线性回归将因子变量理解为分类变量。
  • “没用”非常含糊。无论如何,祝你好运。

标签: r


【解决方案1】:

这是我最喜欢的用于从分类变量创建虚拟变量的代码。 唯一的区别是这段代码产生K-1 虚拟变量以避免共线性:

x = as.factor( rep(1:6,each=4) );
model.matrix(~x)[,-1]

用您数据集中的年份替换x

【讨论】:

  • 这不起作用并引发尺寸错误
  • 在运行代码之前不要忘记将as.factor 应用到年份列。
  • model.matrix(~as.factor(DF$year))[,-1]
  • 好的,这可行,但我仍然需要将它附加到我的原始数据集才能运行回归。谢谢
  • cbind(DF,model.matrix(~as.factor(DF$year))[,-1])
【解决方案2】:

也许是这个?

library(tidyr)
DF$row <- 1:nrow(DF)  # to make each row unique
DF$dummy <- 1

newdf <- spread(DF, year, dummy, fill = 0)

【讨论】:

  • 这可行,但将年份列从 data.frame 中删除
  • @Amstell 没问题:newdf$year = DF$year.
【解决方案3】:
 for(i in unique(DF$year)) {
          DF[paste('year',i,sep="")]=DF$year==i
  }

【讨论】:

  • @Amstell 没问题:只需换上as.numeric()
【解决方案4】:

正如 Andrey Shabalin 所说,你想要model.matrix。首先,您需要将year 列转换为一个因素。为了得到你想要的,你需要使用contr.ltfr,它是caret包中contr.treatment的修改版。

在下面的公式中,0 表示不使用截距,. 表示数据框中的所有列。

DF$year <- factor(DF$year)
model.matrix(
  ~ 0 + ., 
  DF, 
  contrasts.arg = list(year = "contr.ltfr")
)

【讨论】:

  • 感谢您的回答,但我当前的数据集中有 166 个变量,我正在寻找最快的方法来执行此操作,无需 ifelse 并列出我想要保留的所有变量。跨度>
  • 不用粘贴公式,直接改成~ . + 0即可。
【解决方案5】:

只需使用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

如果您希望名称为“year_2010”等,我想一种解决方法是执行以下操作:

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 即可获得您期望的输出。

【讨论】:

  • 这是个好主意。现在做笔记。加一。 :)
  • 这行得通,但每当我点击 Rstudio 中的数据时,虚拟变量都不会出现。你知道为什么吗?
  • @Amstell,你分配输出了吗?
  • @AnandaMahto 是的。就像在 DF
  • @Amstell,dim(DF) 是否提供了您期望的尺寸? names(DF) 是否为您提供了您期望的列名?没有更多细节就很难说。
猜你喜欢
  • 2018-10-01
  • 2015-01-29
  • 1970-01-01
  • 2016-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-07
相关资源
最近更新 更多