Reputation: 903
I have a dataframe, df
, with a a number of columns of data already. I have a vector, namevector
, full of strings. I need empty columns added to df
with the names of the columns from namevector
.
I am trying to add columns with this for loop, iterating over each string in namevector
.
for (i in length(namevector)) {
df[, i] <- NA
}
but am left with this error:
Error in
[<-.data.frame
(*tmp*
, , i, value = NA) : new columns would leave holes after existing columns
Alternatively, I have thought of creating an empty dataframe with the correct names, then cbind
-ing the two dataframes together but am not sure how to go about coding this.
How would I go about resolving this?
Upvotes: 62
Views: 203078
Reputation: 18722
I prefer the base R solution, but here is a tidyverse
solution. Below uses mutate
, but the syntax is the same if you were to use tibble::add_column
:
library(dplyr)
new_columns <- c("A", "B", "C")
iris %>%
mutate(!!!setNames(rep(NA, length(new_columns)), new_columns))
The splice operator uses the name-value pair from setNames
to create the columns.
If you had name-value pairs in a list already then you can simply do:
new_columns <- list(A = NA, B = 1, C = "c")
iris %>%
mutate(!!!new_columns)
If the length of each list element is 1 then its value is recycled. Otherwise, it needs to have the same length as the data frame (e.g. list(A = 1:150)
).
Upvotes: 7
Reputation: 561
A different way to add empty columns to a dataframe.
df <- data.frame(name0 = c(1,2,3))
namevector <- c("name1", "name2", "name3")
sapply(namevector, function(x){df[x] <<- numeric()})
Upvotes: 1
Reputation: 470
The below works for me
dataframe[,"newName"] <- NA
Make sure to add ""
for new name string.
Upvotes: 17
Reputation: 7794
set.seed(1)
example <- data.frame(col1 = rnorm(10, 0, 1), col2 = rnorm(10, 2, 3))
namevector <- c("col3", "col4")
example[ , namevector] <- NA
example
# col1 col2 col3 col4
# 1 -0.6264538 6.5353435 NA NA
# 2 0.1836433 3.1695297 NA NA
# 3 -0.8356286 0.1362783 NA NA
# 4 1.5952808 -4.6440997 NA NA
# 5 0.3295078 5.3747928 NA NA
# 6 -0.8204684 1.8651992 NA NA
# 7 0.4874291 1.9514292 NA NA
# 8 0.7383247 4.8315086 NA NA
# 9 0.5757814 4.4636636 NA NA
# 10 -0.3053884 3.7817040 NA NA
Upvotes: 30
Reputation: 17432
The problem with your code is in the line:
for(i in length(namevector))
You need to ask yourself: what is length(namevector)
? It's one number. So essentially you're saying:
for(i in 11)
df[,i] <- NA
Or more simply:
df[,11] <- NA
That's why you're getting an error. What you want is:
for(i in namevector)
df[,i] <- NA
Or more simply:
df[,namevector] <- NA
Upvotes: 84
Reputation: 1079
Maybe
df <- do.call("cbind", list(df, rep(list(NA),length(namevector))))
colnames(df)[-1*(1:(ncol(df) - length(namevector)))] <- namevector
Upvotes: -2