简体   繁体   中英

Fill a column with values from a table (or matrix) given certain conditions

I'm not sure exactly what this would be called, so I'm struggling to search for it. Sorry if this is a repeated question, that would be why.

I have a data 43x17 data matrix,lets call it A, with four levels in the "site" column. I also have another 4x3 matrix containing coordinates for each site, lets call it B. I'd like to create a column in A where each site is assigned the coordinate listed in B.

Using the data below as an example, I'd like to make a new column in A and populate it with values from Coordinate1 (in B) with the associated "Site" value.

A <- matrix(c(1:4), nrow = 12, ncol = 3, byrow = TRUE,
               dimnames = list(c(1:12),
                               c("Site", "D.2", "D.3")))
A
B<- matrix(c(1:4), nrow = 4, ncol = 3, byrow = TRUE,
           dimnames = list(c(1:4),
                           c("Site", "Coordinate1", "Coordinate2")))
B

I'm sure this is simple, but I'm blanking on what to call this and have apparently forgotten how to do it!

There are several options.

Without conversion to data.frame and using merge() as suggested in most of the comments, you may try to use match() and cbind() :

cbind(A, B[match(A[, "Site"], B[, "Site"]), "Coordinate1", drop = FALSE])
  Site D.2 D.3 Coordinate1 1 1 2 3 2 2 4 1 2 1 3 3 4 1 4 4 2 3 4 3 5 1 2 3 2 6 4 1 2 1 7 3 4 1 4 8 2 3 4 3 9 1 2 3 2 10 4 1 2 1 11 3 4 1 4 12 2 3 4 3 

or, to cbind all columns of B

cbind(A, B[match(A[, "Site"], B[, "Site"]), ])
  Site D.2 D.3 Site Coordinate1 Coordinate2 1 1 2 3 1 2 3 2 4 1 2 4 1 2 3 3 4 1 3 4 1 4 2 3 4 2 3 4 5 1 2 3 1 2 3 6 4 1 2 4 1 2 7 3 4 1 3 4 1 8 2 3 4 2 3 4 9 1 2 3 1 2 3 10 4 1 2 4 1 2 11 3 4 1 3 4 1 12 2 3 4 2 3 4 

Conversion to data.frame and merge()

 as.matrix(merge(data.frame(A), data.frame(B), by = "Site", sort = FALSE))

distorts the original order of rows:

  Site D.2 D.3 Coordinate1 Coordinate2 [1,] 1 2 3 2 3 [2,] 1 2 3 2 3 [3,] 1 2 3 2 3 [4,] 4 1 2 1 2 [5,] 4 1 2 1 2 [6,] 4 1 2 1 2 [7,] 3 4 1 4 1 [8,] 3 4 1 4 1 [9,] 3 4 1 4 1 [10,] 2 3 4 3 4 [11,] 2 3 4 3 4 [12,] 2 3 4 3 4 

Using right join from the data.table package maintains the order of rows

library(data.table)
as.matrix(data.table(B)[data.table(A), on = "Site"])
  Site Coordinate1 Coordinate2 D.2 D.3 [1,] 1 2 3 2 3 [2,] 4 1 2 1 2 [3,] 3 4 1 4 1 [4,] 2 3 4 3 4 [5,] 1 2 3 2 3 [6,] 4 1 2 1 2 [7,] 3 4 1 4 1 [8,] 2 3 4 3 4 [9,] 1 2 3 2 3 [10,] 4 1 2 1 2 [11,] 3 4 1 4 1 [12,] 2 3 4 3 4 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM