R: losing column names when adding rows to an empty data frame

前端 未结 8 1144
旧时难觅i
旧时难觅i 2020-12-05 01:36

I am just starting with R and encountered a strange behaviour: when inserting the first row in an empty data frame, the original column names get lost.

example:

相关标签:
8条回答
  • 2020-12-05 01:52

    I use the following solution to add a row to an empty data frame:

    d_dataset <- 
      data.frame(
        variable = character(),
        before = numeric(),
        after = numeric(),
        stringsAsFactors = FALSE)
    
    d_dataset <- 
      rbind(
        d_dataset,
          data.frame(
            variable = "test",
            before = 9,
            after = 12,
            stringsAsFactors = FALSE))  
    
    print(d_dataset)
    
    variable before after  
    1     test      9    12
    

    HTH.

    Kind regards

    Georg

    0 讨论(0)
  • 2020-12-05 01:54

    FWIW, an alternative design might have your functions building vectors for the two columns, instead of rbinding to a data frame:

    ones <- c()
    twos <- c()
    

    Modify the vectors in your functions:

    ones <- append(ones, 5)
    twos <- append(twos, 6)
    

    Repeat as needed, then create your data.frame in one go:

    a <- data.frame(one=ones, two=twos)
    
    0 讨论(0)
  • 2020-12-05 01:57

    Instead of constructing the data.frame with numeric(0) I use as.numeric(0).

    a<-data.frame(one=as.numeric(0), two=as.numeric(0))
    

    This creates an extra initial row

    a
    #    one two
    #1   0   0
    

    Bind the additional rows

    a<-rbind(a,c(5,6))
    a
    #    one two
    #1   0   0
    #2   5   6
    

    Then use negative indexing to remove the first (bogus) row

    a<-a[-1,]
    a
    
    #    one two
    #2   5   6
    

    Note: it messes up the index (far left). I haven't figured out how to prevent that (anyone else?), but most of the time it probably doesn't matter.

    0 讨论(0)
  • 2020-12-05 01:58

    was almost surrendering to this issue.

    1) create data frame with stringsAsFactor set to FALSE or you run straight into the next issue

    2) don't use rbind - no idea why on earth it is messing up the column names. simply do it this way:

    df[nrow(df)+1,] <- c("d","gsgsgd",4)

    df <- data.frame(a = character(0), b=character(0), c=numeric(0))
    
    df[nrow(df)+1,] <- c("d","gsgsgd",4)
    
    #Warnmeldungen:
    #1: In `[<-.factor`(`*tmp*`, iseq, value = "d") :
    #  invalid factor level, NAs generated
    #2: In `[<-.factor`(`*tmp*`, iseq, value = "gsgsgd") :
    #  invalid factor level, NAs generated
    
    df <- data.frame(a = character(0), b=character(0), c=numeric(0), stringsAsFactors=F)
    
    df[nrow(df)+1,] <- c("d","gsgsgd",4)
    
    df
    #  a      b c
    #1 d gsgsgd 4
    
    0 讨论(0)
  • 2020-12-05 02:03

    One way to make this work generically and with the least amount of re-typing the column names is the following. This method doesn't require hacking the NA or 0.

    rs <- data.frame(i=numeric(), square=numeric(), cube=numeric())
    for (i in 1:4) {
        calc <- c(i, i^2, i^3)
        # append calc to rs
        names(calc) <- names(rs)
        rs <- rbind(rs, as.list(calc))
    }
    

    rs will have the correct names

    > rs
        i square cube
    1   1      1    1
    2   2      4    8
    3   3      9   27
    4   4     16   64
    > 
    

    Another way to do this more cleanly is to use data.table:

    > df <- data.frame(a=numeric(0), b=numeric(0))
    > rbind(df, list(1,2)) # column names are messed up
    >   X1 X2
    > 1  1  2
    
    > df <- data.table(a=numeric(0), b=numeric(0))
    > rbind(df, list(1,2)) # column names are preserved
       a b
    1: 1 2
    

    Notice that a data.table is also a data.frame.

    > class(df)
    "data.table" "data.frame"
    
    0 讨论(0)
  • 2020-12-05 02:12

    Workaround would be:

    a <- rbind(a, data.frame(one = 5, two = 6))
    

    ?rbind states that merging objects demands matching names:

    It then takes the classes of the columns from the first data frame, and matches columns by name (rather than by position)

    0 讨论(0)
提交回复
热议问题