Using cbind on an arbitrarily long list of objects

前端 未结 4 817
悲哀的现实
悲哀的现实 2020-11-29 09:03

I would like to find a way to create a data.frame by using cbind() to join together many separate objects. For example, if A, B, C & D are all vectors of eq

4条回答
  •  忘掉有多难
    2020-11-29 09:51

    First you need to get the objects you want and store them together as a list; if you can construct their names as strings, you use the get function. Here I create two variables, A and B:

    > A <- 1:4
    > B <- rep(LETTERS[1:2],2)
    

    I then construct a character vector containing their names (stored as ns) and get these variables using lapply. I then set the names of the list to be the same as their original names.

    > (ns <- LETTERS[1:2])
    [1] "A" "B"
    > obj.list <- lapply(ns, get)
    > names(obj.list) <- ns
    > obj.list
    $A
    [1] 1 2 3 4
    
    $B
    [1] "A" "B" "A" "B"
    

    Then you can use do.call; the first argument is the function you want and the second is a list with the arguments you want to pass to it.

    > do.call(cbind, obj.list)
         A   B  
    [1,] "1" "A"
    [2,] "2" "B"
    [3,] "3" "A"
    [4,] "4" "B"
    

    However, as aL3xa correctly notes, this makes a matrix, not a data frame, which may not be what you want if the variables are different classes; here my A has been coerced to a character vector instead of a numeric vector. To make a data frame from a list, you just call data.frame on it; then the classes of the variables are retained.

    > (AB <- data.frame(obj.list))
      A B
    1 1 A
    2 2 B
    3 3 A
    4 4 B
    > sapply(AB, class)
            A         B 
    "integer"  "factor" 
    > str(AB)
    'data.frame':   4 obs. of  2 variables:
     $ A: int  1 2 3 4
     $ B: Factor w/ 2 levels "A","B": 1 2 1 2
    

提交回复
热议问题