YYY
YYY

Reputation: 625

how to create a new dataframe by existing one?

I have a datafame which has 10 columns, say (a1-a10). I'd like to create a new one which has thirty columns, say (a1,b1,c1,...a10,b10,c10), by copying from the smaller one. If the columns doesn't exist in smaller one, the columns will be left as blank in the larger one. Is there any way to implement this without loop comparing and copying. Thank you very much for any help and suggestion.

Upvotes: 1

Views: 4788

Answers (3)

Dinre
Dinre

Reputation: 4216

Assuming the names match, this isn't too difficult to vectorize. I'm going to use a simple data frame as an example.

data_1 <- data.frame(a=1:20, b=2:21, c=3:22)

First, we need to initialize the new data frame.

data_2 <- data.frame(e=rep(NA, nrow(data_1)), b=NA, a=NA, d=NA)

Now, we copy everything over, taking care not to assume that the new columns are in the same order. I've stretched this out into more lines than is necessary to make the example easier to follow.

matched_columns <- match(names(data_1), names(data_2))
copy_column <- !is.na(matched_columns)
destination_column <- matched_columns[copy_column]

data_2[,destination_column] <- data_1[,copy_column]

What we have done here is to find the indices of matching column names, create a vector of TRUE/FALSE for presence of a data_1 column in data_2, and then use those indices to copy over data from data_1 into data_2.

Upvotes: 1

Gregor Thomas
Gregor Thomas

Reputation: 145765

Something like this. Note that most of the code is just creating a suitable test case:

old_df <- data.frame(a1 = rnorm(10), a5 = rnorm(10))
new_names <- paste0("a", 1:30)

Create your new data.frame() with whatever names you want.

new_df <- as.data.frame(matrix(NA, nrow= nrow(old_df), ncol = length(new_names)))
names(new_df) <- new_names

This just replaces any column that have the names in the old data.frame with the columns from the old data.frame. Won't work unless the new one has the same number of rows!

new_df[, names(old_df)] <- old_df  # This is the line you want

Upvotes: 2

TomR
TomR

Reputation: 546

I'm not entirely sure what you're asking in terms of loop comparing and copying, but this will do it with small modifications for your particular data set (whatever that looks like):

a <- c(1,2,3)
b <- c("a","b","c")
c <- c("do", "re", "mi")

mydf <- data.frame(a,b,c)

mynewdf <- data.frame(matrix(vector(), dim(mydf)[1] , 0))

for(i in 1:dim(mydf)[2]){
  for(j in 1:3){
    mynewdf <- cbind(mynewdf, mydf[ ,i])
    colnames(mynewdf)[dim(mynewdf)[2]] <- paste(colnames(mydf)[i],as.character(j))
    }
  }

Upvotes: 0

Related Questions