R - 使用带有for循环的其他变量在数据框中创建变量

时间:2014-11-29 15:53:57

标签: r

很抱歉,如果这个问题太简单了,但对于我的生活却无法解决这个问题。

我有一个带有连续变量的数据框,需要根据连续变量的值创建多个逻辑变量。

希望下面的例子说明了这一点:

x <- as.integer(rnorm(n=1000, mean=10, sd=5))

y <- 1:1000

df <- data.frame(x,y)

for i in 1:10 {

  df$[i] <- ifelse (df$x<[i],1,0)

}

我怀疑我在df$[i]表达式出错...任何解决方案?

提前致谢

2 个答案:

答案 0 :(得分:1)

您可以通过分配新的列轻松地向data.frame添加新列。在LHS上指定列解除引用,并在RHS上指定计算向量的表达式,该向量应与data.frame中已存在的其他列具有相同的长度。例如,如果要添加一个逻辑列,捕获同一行中的x值是否小于用于计算所有x值的正态分布的平均值,则可以执行以下操作:

df$z <- df$x<10;

您不需要for循环来执行此操作。 R中的许多操作都是矢量化的,这意味着它们会自动循环遍历矢量操作数的所有元素。该行代码中的df$x<10代码段测试df $ x中1000个值中的每一个,以查看它是否小于10,并且整个操作返回1000个逻辑值的向量(每个都为TRUE, FALSE,或NA)与矢量化操作的结果。因此,您可以将结果直接分配给data.frame中的新列。

答案 1 :(得分:0)

可能是您想要的(使用您的代码)

for(i in 1:10){
  df[paste0("Col",i)] <- ifelse(df$x <i, 1, 0)
 }

 head(df,3)
 #   x y Col1 Col2 Col3 Col4 Col5 Col6 Col7 Col8 Col9 Col10
 #1  7 1    0    0    0    0    0    0    0    1    1     1
 #2 12 2    0    0    0    0    0    0    0    0    0     0
 #3 12 3    0    0    0    0    0    0    0    0    0     0

或者

 df[paste0('Col',1:10)] <- Vectorize(function(x) df$x < x)(1:10)+0

或者

 df[paste0('Col', 1:10)] <-  (do.call(cbind,Map(`<`, list(df$x), 1:10)))+0

或者

df[paste0('Col', 1:10)] <- matrix((df$x < rep(1:10, each=nrow(df)))+0, ncol=10)

或者

df[paste0('Col', 1:10)] <- `dim<-` ((df$x < rep(1:10, each=nrow(df)))+0,
                                               c(nrow(df),10))

数据

set.seed(24)
x <- as.integer(rnorm(n=1000, mean=10, sd=5))
y <- 1:1000
df <- data.frame(x,y)