对R中的if语句和for循环感到困惑

对R中的if语句和for循环感到困惑,r,if-statement,for-loop,dataframe,R,If Statement,For Loop,Dataframe,所以我在R中有一个数据框,其中一列是几个因子的变量,我想为每个因子创建几个虚拟变量,但是当我写一个循环来做这件事时,我得到了一个错误 例如,如果列由各种因素a、b、c组成,我想为每个因素编码一个1或0的伪变量,我必须创建一个伪变量的代码是: h = rep(0, nrow(data)) for (i in 1:nrow(data)) { if (data[,1] == "a") { h[i] = 1 } else { h[i] = 0 } } cbind(data,

所以我在R中有一个数据框,其中一列是几个因子的变量,我想为每个因子创建几个虚拟变量,但是当我写一个循环来做这件事时,我得到了一个错误

例如,如果列由各种因素a、b、c组成,我想为每个因素编码一个1或0的伪变量,我必须创建一个伪变量的代码是:

h = rep(0, nrow(data))
for (i in 1:nrow(data)) {
  if (data[,1] == "a") {
    h[i] = 1
  } else {
    h[i] = 0
  }
}
cbind(data, h)
这给了我一条错误消息“条件的长度大于1,只有第一个元素会被使用”,我在这个网站的其他地方看到过这样的消息,说我应该尝试编写自己的函数来解决问题,避免循环,我真的不明白a)如何通过编写函数来解决这个问题(至少立即)b)作为一个函数而不是使用循环进行此操作的好处


最后,我还使用ifelse语句创建了每个向量,然后cbind将其添加到数据帧中,不过我希望能给出一个解释。

if(data[,1]=“a”){
更改为
if(data[I,1]=“a”){
if(data[,1]=“a”){
更改为
if(data[I,1]=“a”){

Aakash指出循环中的问题是正确的。您的测试是

if (data[,1] == "a")
由于您的测试不依赖于
i
,因此每次迭代都是相同的。您可以这样修复循环:

h = rep(0, nrow(data))
for (i in 1:nrow(data)) {
  if (data[i, 1] == "a")
    h[i] = 1
  } else {
    h[i] = 0
  }
}
我们甚至可以简化,因为
h
被初始化为0,所以在
else
情况下不需要将其设置为0,我们可以继续:

for (i in 1:nrow(data)) {
  if (data[i, 1] == "a")
    h[i] = 1
  }
}
一个更实质性的改进是引入矢量化。这将加快您的代码速度,并且在掌握了窍门后通常更易于编写。
如果
只能检查一个条件,但如果对其他进行了矢量化,则需要一个测试向量,一个“if true”结果向量,一个“if false”向量结果,并将它们结合起来:

h = ifelse(data[, 1] == "a", 1, 0)
这样,就不需要在语句之前初始化
h
,我们可以直接将其添加到数据帧中:

data$h = ifelse(data[, 1] == "a", 1, 0)
在本例中,您的测试用例和结果非常简单,我们可以做得更好

data[, 1] == "a" ## run this and look at the output
上面的代码只是
TRUE
FALSE
的布尔向量。如果我们在上面运行
as.numeric()
,则真值将强制为1s,假值将强制为0s。所以我们可以这样做

data$h = as.numeric(data[, 1] == "a")
这将比ifelse更有效


此操作非常简单,编写函数来执行此操作没有任何好处。

Aakash指出循环中的问题是正确的。您的测试是

if (data[,1] == "a")
由于您的测试不依赖于
i
,因此每次迭代都是相同的。您可以这样修复循环:

h = rep(0, nrow(data))
for (i in 1:nrow(data)) {
  if (data[i, 1] == "a")
    h[i] = 1
  } else {
    h[i] = 0
  }
}
我们甚至可以简化,因为
h
被初始化为0,所以在
else
情况下不需要将其设置为0,我们可以继续:

for (i in 1:nrow(data)) {
  if (data[i, 1] == "a")
    h[i] = 1
  }
}
一个更实质性的改进是引入矢量化。这将加快您的代码速度,并且在掌握了窍门后通常更易于编写。
如果
只能检查一个条件,但如果对其他进行了矢量化,则需要一个测试向量,一个“if true”结果向量,一个“if false”向量结果,并将它们结合起来:

h = ifelse(data[, 1] == "a", 1, 0)
这样,就不需要在语句之前初始化
h
,我们可以直接将其添加到数据帧中:

data$h = ifelse(data[, 1] == "a", 1, 0)
在本例中,您的测试用例和结果非常简单,我们可以做得更好

data[, 1] == "a" ## run this and look at the output
上面的代码只是
TRUE
FALSE
的布尔向量。如果我们在上面运行
as.numeric()
,则真值将强制为1s,假值将强制为0s。所以我们可以这样做

data$h = as.numeric(data[, 1] == "a")
这将比ifelse更有效


此操作非常简单,编写函数来执行此操作没有任何好处。

data[,1]
是一个向量,如果未对其进行向量化,
data$h可能重复:,密切相关:啊,抱歉,在发布
data[,1]之前,我肯定没有看到这一点
是一个向量,如果
没有向量化,
数据$h可能重复:,密切相关:啊,很抱歉我在发布之前没有看到这一点谢谢你的帮助,我真的很感激!令人惊讶的是有很多不同的方法可以做同样的事情哈哈。谢谢你的帮助,我真的很感激!这是amazing有多少种不同的方法可以做同样的事情哈哈。