How to add a row to a data frame in R?
Like @Khashaa and @Richard Scriven point out in comments, you have to set consistent column names for all the data frames you want to append.
Hence, you need to explicitly declare the columns names for the second data frame, de
, then use rbind()
. You only set column names for the first data frame, df
:
df<-data.frame("hi","bye")
names(df)<-c("hello","goodbye")
de<-data.frame("hola","ciao")
names(de)<-c("hello","goodbye")
newdf <- rbind(df, de)
How to append rows to an R data frame
Update
Not knowing what you are trying to do, I'll share one more suggestion: Preallocate vectors of the type you want for each column, insert values into those vectors, and then, at the end, create your data.frame
.
Continuing with Julian's f3
(a preallocated data.frame
) as the fastest option so far, defined as:
# pre-allocate space
f3 <- function(n){
df <- data.frame(x = numeric(n), y = character(n), stringsAsFactors = FALSE)
for(i in 1:n){
df$x[i] <- i
df$y[i] <- toString(i)
}
df
}
Here's a similar approach, but one where the data.frame
is created as the last step.
# Use preallocated vectors
f4 <- function(n) {
x <- numeric(n)
y <- character(n)
for (i in 1:n) {
x[i] <- i
y[i] <- i
}
data.frame(x, y, stringsAsFactors=FALSE)
}
microbenchmark
from the "microbenchmark" package will give us more comprehensive insight than system.time
:
library(microbenchmark)
microbenchmark(f1(1000), f3(1000), f4(1000), times = 5)
# Unit: milliseconds
# expr min lq median uq max neval
# f1(1000) 1024.539618 1029.693877 1045.972666 1055.25931 1112.769176 5
# f3(1000) 149.417636 150.529011 150.827393 151.02230 160.637845 5
# f4(1000) 7.872647 7.892395 7.901151 7.95077 8.049581 5
f1()
(the approach below) is incredibly inefficient because of how often it calls data.frame
and because growing objects that way is generally slow in R. f3()
is much improved due to preallocation, but the data.frame
structure itself might be part of the bottleneck here. f4()
tries to bypass that bottleneck without compromising the approach you want to take.
Original answer
This is really not a good idea, but if you wanted to do it this way, I guess you can try:
for (i in 1:10) {
df <- rbind(df, data.frame(x = i, y = toString(i)))
}
Note that in your code, there is one other problem:
- You should use
stringsAsFactors
if you want the characters to not get converted to factors. Use:df = data.frame(x = numeric(), y = character(), stringsAsFactors = FALSE)
Create an empty dataframe and append rows to it in R
You need to store the result of rbind back into AvsB in each loop:
datosA <- read_excel(archivo, col_names = TRUE, sheet = "Sheet1")
datosB <- read_excel(archivo, col_names = TRUE, sheet = "Sheet1")
AvsB <- data.frame()
for (x in datosA$'m/z') {
if (!(x %in% datosB$'m/z')) {
index <- match(x, datosA$'m/z')
AvsB <- rbind(AvsB, datosA[index,])
}
}
How to append rows as new columns of a dataframe R
One possibility involving dplyr
and tidyr
could be:
df %>%
mutate(grp = cumsum(!grepl("text", V1, fixed = TRUE))) %>%
gather(var, val, -grp) %>%
group_by(grp) %>%
mutate(var = paste0("V", row_number())) %>%
ungroup() %>%
spread(var, val) %>%
select(-grp)
V1 V2 V3 V4 V5 V6
<chr> <chr> <chr> <chr> <chr> <chr>
1 1234 text1 data1 data2 <NA> <NA>
2 2345 text1 text2 data3 data4 data5
3 3456 text1 data6 data7 <NA> <NA>
Or if you want to match your desired output exactly:
df %>%
group_by(grp = cumsum(!grepl("text", V1, fixed = TRUE))) %>%
mutate(grp2 = row_number()) %>%
ungroup() %>%
gather(var, val, -c(grp, grp2)) %>%
arrange(grp, grp2) %>%
group_by(grp) %>%
mutate(var = paste0("V", row_number())) %>%
ungroup() %>%
select(-grp2) %>%
spread(var, val) %>%
select(-grp)
V1 V2 V3 V4 V5 V6
<chr> <chr> <chr> <chr> <chr> <chr>
1 1234 data1 text1 data2 <NA> <NA>
2 2345 data3 text1 data4 text2 data5
3 3456 data6 text1 data7 <NA> <NA>
How to add row to dataframe?
You are trying to add a vector and rbind
it with data frame which is not the best option. You better rbind
a data.frame
to data.frame
.
So in your case better to do:
for (state in unique(data$state)) {
means<-rbind(means, data.frame(State=state,Mean=4)
}
Add a value as a new row to a dataframe but keep all other columns NA
A possible solution, based on dplyr
. We first need to convert ID
from numeric
to character
.
library(dplyr)
mydata %>%
mutate(ID = as.character(ID)) %>%
bind_rows(list(ID = "School 1"), .)
#> # A tibble: 6 × 3
#> ID subject age
#> <chr> <chr> <dbl>
#> 1 School 1 <NA> NA
#> 2 1 His 21
#> 3 2 Geo 24
#> 4 3 Geo 26
#> 5 4 His 23
#> 6 5 Geo 26
How can I add several NA's as rows to data frame?
Similar to GKi's solution but without rbind()
:
df[c(rep(NA, 4L), seq_len(nrow(df))), ]
# X1.3 X4.6 X7.9
# NA NA NA NA
# NA.1 NA NA NA
# NA.2 NA NA NA
# NA.3 NA NA NA
# 1 1 4 7
# 2 2 5 8
# 3 3 6 9
Related Topics
How to Change the Background Color of a Plot Made with Ggplot2
Returning Anonymous Functions from Lapply - What Is Going Wrong
R Extract Rows Where Column Greater Than 40
How to Reorder Data.Table Columns (Without Copying)
Remove All Line Breaks (Enter Symbols) from the String Using R
Way to Securely Give a Password to R Application from the Terminal
No Rtools Compatible with R Version 3.5.0 Was Found
How Convert Decimal to Posix Time
Fully Reproducible Parallel Models Using Caret
Dynamic Column Names in Data.Table
Marker Mouse Click Event in R Leaflet for Shiny
Put a Break in the Y-Axis of a Histogram
Dplyr/R Cumulative Sum with Reset
What's the Difference Between Integer Class and Numeric Class in R