1

Sorry if this is too simple a question but for the life of me cant sort this out.

I have a data frame with a continuous variable and need to create multiple logical variables based on the value of the continuous variable.

Hopefully the example below illustrates this:

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)

}

I suspect I am going wrong at the df$[i] expression...any solutions?

Thanks in advance

0

2 Answers 2

1

You can add new columns to a data.frame easily by assigning to them. On the LHS specify the column dereference and on the RHS specify an expression that computes to a vector, which should have the same length as the other columns that already exist in the data.frame. For example, if you want to add a logical column that captures if the x value in the same row is less than the mean of the normal distribution you used to calculate all x values, you can do this:

df$z <- df$x<10;

You don't need a for loop to do this. Many operations in R are vectorized, meaning they automatically loop through all elements of vector operands. The df$x<10 snippet in that line of code tests every one of the 1000 values in df$x to see if it's less than 10, and the whole operation returns a vector of 1000 logical values (each TRUE, FALSE, or NA) with the results of the vectorized operation. So you can assign that result directly to a new column in the data.frame.

Sign up to request clarification or add additional context in comments.

Comments

0

May be you want (using your code)

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

Or

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

Or

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

Or

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

Or

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

data

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

1 Comment

worked like a charm akrun - cheers buddy!!! saved me oodles of time. One of the great reasons why i love the R community!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.