How to Rbind Vectors Matching Their Column Names

How can I rbind vectors matching their column names?

You can use match:

l <- list(row1 = setNames(1:3, c("A", "B", "C")),
row2 = setNames(1:3, c("B", "C", "A")),
row3 = setNames(1:3, c("C", "A", "B")))

do.call(rbind, lapply(l, function(x) x[match(names(l[[1]]), names(x))]))

The result:

     A B C
row1 1 2 3
row2 3 1 2
row3 2 3 1

rbind in R - matching the column names

You can try:

#Data
result <- structure(list(size = structure(1:4, .Label = c("big", "medium",
"small", "tiny"), class = "factor"), KUALALUMPUR = c(0, 187.874,
435.344, 0), OTHERS = c(116.861, 9656.649, 245.598, 0), PENANG = c(138.366,
0, 333.317, 0), SELANGOR = c(NA, NA, NA, NA), DARUL = c(NA, NA,
NA, NA), EHSAN = c(0, 0, 272.342, 0), TOTAL = c(136.207, 223.415,
348.692, 0)), class = "data.frame", row.names = c(NA, -4L))

#Compute totals
vec <- as.data.frame(t(c(size='TOTAL',colSums(result[,-c(1,8)],na.rm=T),TOTAL=NA)))
#Bind
DF <- rbind(result,vec)

size KUALALUMPUR OTHERS PENANG SELANGOR DARUL EHSAN TOTAL
1 big 0 116.861 138.366 <NA> <NA> 0 136.207
2 medium 187.874 9656.649 0 <NA> <NA> 0 223.415
3 small 435.344 245.598 333.317 <NA> <NA> 272.342 348.692
4 tiny 0 0 0 <NA> <NA> 0 0
5 TOTAL 623.218 10019.108 471.683 0 0 272.342 <NA>

Or using your second dataframe:

#Data
SummaryRegion <- structure(list(experience = c(156.523, 272.342, 343.998, 296.601
), region1 = structure(c(4L, 1L, 2L, 3L), .Label = c("EHSAN",
"KUALALUMPUR", "OTHERS", "PENANG"), class = "factor")), class = "data.frame", row.names = c("PENANG",
"EHSAN", "KUALALUMPUR", "OTHERS"))

library(plyr)
#Using provided df
rownames(SummaryRegion)<-SummaryRegion$region1
vec2 <- as.data.frame(t(SummaryRegion[,c(1),drop=F]))
DF2 <- rbind.fill(result,vec2)

size KUALALUMPUR OTHERS PENANG SELANGOR DARUL EHSAN TOTAL
1 big 0.000 116.861 138.366 NA NA 0.000 136.207
2 medium 187.874 9656.649 0.000 NA NA 0.000 223.415
3 small 435.344 245.598 333.317 NA NA 272.342 348.692
4 tiny 0.000 0.000 0.000 NA NA 0.000 0.000
5 <NA> 343.998 296.601 156.523 NA NA 272.342 NA

Combine two data frames by rows (rbind) when they have different sets of columns

rbind.fill from the package plyr might be what you are looking for.

How can I automatically name columns in rbind?

You can use a combination of rbind and mget:

v1 <- 1
v2 <- 2

rbind(mget(c("v1", "v2")), mget(c("v1", "v2")))

mget will search the environment for variables with the given names. Most importantly, the result is a named list object.

However, I think a cleaner solution is to just make a data.frame, as suggested above:

rbind(data.frame(v1, v2), data.frame(v1, v2))

rbind based on columns name and exclude no match

Here's one way to do it:

match_all_columns <- function (d, col) {
if (all(names(d) %in% col)) {
out <- d[, col]
} else {
out <- NULL
}
out
}
# or as a one-liner
match_all_columns <- function (d, col) if (all(names(d) %in% col)) d[col]

matched_data <- lapply(l, match_all_columns, col)
result <- do.call(rbind, matched_data)
result
# X1 X2 X3 X4 X5
# x 1 2 3 4 5
# z 11 12 13 14 15

rbind knows to just ignore the NULL elements.

edit: I swapped d[, col] with d[col] because a) it looks nicer, b) it prevents the data frame being dropped to a vector if col only has one element, and c) I think it's slightly more performant on large data frames.

How to name the columns of my with rbind generated matrix in R?

If the vectors you have should be columns in the output dataframe, than you need to use cbind() function:

# first vector
v1 <- rnorm(1:10)

#second vector
v2<- 1:10

# third vector
v3 <- runif(10, min=-10, max=10)

# names for the columns:
cnames <- c("first", "second", "third")

# combine your vectors as columns
my.data<- cbind(v1, v2, v3)
colnames(my.data) <- cnames

# The above result is a matrix. You can convert it to data frame if necessary
my.data <- as.data.frame(my.data)
my.data
# first second third
# 1 0.1546350 1 1.441857
# 2 0.1954627 2 -2.557443
# 3 1.0097335 3 2.856407
# 4 -0.6707548 4 2.244222
# 5 0.6522662 5 -5.248731
# 6 -0.4794330 6 -1.406135
# 7 -1.3191673 7 6.687989
# 8 0.4762472 8 1.562045
# 9 0.7190201 9 -1.301451
# 10 0.3914469 10 2.100174

If the vectors you have are the rows in your future data frame, then:

# first vector
v1 <- rnorm(1:3)

#second vector
v2<- rnorm(1:3)

# third vector
v3 <- rnorm(1:3)

# forth vector
v4 <- rnorm(1:3)

# names for the columns:
cnames <- c("first", "second", "third")

# combine your vectors as columns
my.data<- rbind(v1, v2, v3, v4)
colnames(my.data) <- cnames

# The above result is a matrix. You can convert it to data frame if necessary
my.data <- as.data.frame(my.data)
my.data
# first second third
#v1 0.2637774 -0.2010000 0.5637698
#v2 -0.1368421 0.2559511 -1.2920349
#v3 -0.8087293 0.4321634 -0.2470514
#v4 0.1954442 -1.6450399 0.4054812

Combining two vectors with rbind

you were almost there, just don't use c() inside the rbind

ID <- rbind(ID,ID2)

Conditional rbind elements between 2 lists if their names() match; Map()?

You can do this quite efficiently with

nms <- union(names(A), names(B))
l <- Map(rbind, A[nms], B[nms])
names(l) <- nms # needed if 'names(A)' does not contain 'names(B)'


Related Topics



Leave a reply



Submit