Combine Lists While Overriding Values with Same Name in R

Combine lists while overriding values with same name in R

R has a built in function to do that modifyList

modifyList(a, b)

R - merge lists with overwrite and recursion

I am not so sure if a custom function is necessary here. There is a function utils::modifyList() to perform this exact same operation! See modifyList for more info.

a <- list( a=1, b=2, c=list( d=1, e=2 ), d=list( a=1, b=2 ) )
b <- list( a=2, c=list( e=1, f=2 ), d=3, e=2 )

modifyList(a, b) # updates(modifies) 'a' with 'b'

Which gives the following

$a
[1] 2

$b
[1] 2

$c
$c$d
[1] 1

$c$e
[1] 1

$c$f
[1] 2

$d
[1] 3

$e
[1] 2

Rlist, combine elements of the same name (some are lists)

I assume you only want the 1st level and it's not a list. I use dplyr::lst "Note that lst lifecycle's is questioning" because it supports dplyr quasiquotation.

sapply(unique(names(list2)), function(x) {
#browser()
if(sum(names(list2)==x)>=2 & !any(sapply(list2[names(list2)==x], function(l) is.list(l)))){
item <- list2[names(list2)==x]
names(item) <- NULL
dplyr::lst(!!x := item)
} else {
list2[x]
}

}, USE.NAMES = FALSE)

$credit
$credit[[1]]
[1] "Conceptualization"

$credit[[2]]
[1] "Software"

$.attrs
$.attrs$`contrib-type`
[1] "author"

How can I partially update or merge a list in R?

There's a modifyList for these purposes. Note that I corrected list3 definition, there's a mistake in your desired output.

list4 <- modifyList(list1, list2)
list3 <- list(var1=3,var2=list(var21=1,var22=0,var23=list(var231=1,var232=1,var233=2)),var3=list(var31=1))
all.equal(list3, list4)
[1] TRUE

Merging two data frame lists based on comparing two column values according to one-to-one match rule

You may try:

Assuming that the geneData.txt can be read into a two column data.frame with first column for human genes and second for rat genes

geneData <- structure(list(human = c("DOCK10", "NUDT5", "SDHB1", "AAED1", 
"AAGAB"), rat = c("Dok10", "Nud5", "Sdhb", "Aaed1", "Aagab")), .Names = c("human",
"rat"), class = "data.frame", row.names = c(NA, -5L))

res <- merge(merge(geneData, humanlist, by.x="human", by.y="humanGene"), ratlist, by.x="rat", by.y="ratGene")

res[,c(2,4,5,1,7,8)]
# human humanAlignment humanRNAtype rat ratAlignment ratRNAtype
# 1 DOCK10 6 reg Dok10 2 rev

In the example for geneData:

  • NUDT5 is found in humanlist, but Nud5 not in ratlist
  • Sdhb is found in ratlist, but SDHB1 not in humanlist
  • Some gene names are not found in both the lists
  • Here, only Dok10 and DOCK10 are found in both the lists

Merge data frames and overwrite values

merdat <- merge(dfrm1,dfrm2, by="Date")  # seems self-documenting

# explanation for next line in text below.
merdat$Col2.y[ is.na(merdat$Col2.y) ] <- merdat$Col2.x[ is.na(merdat$Col2.y) ]

Then just rename 'merdat$Col2.y' to 'merdat$Col2' and drop 'merdat$Col2.x'.

In reply to request for more comments: One way to update only sections of a vector is to construct a logical vector for indexing and apply it using "[" to both sides of an assignment. Another way is to devise a logical vector that is only on the LHS of an assignment but then make a vector using rep() that has the same length as sum(logical.vector). The goal is both instances is to have the same length (and order) for assignment as the items being replaced.

Merge R data frame or data table and overwrite values of multiple columns

You can do this by using dplyr::coalesce, which will return the first non-missing value from vectors.

(EDIT: you can use dplyr::coalesce directly on the data frames also, no need to create the function below. Left it there just for completeness, as a record of the original answer.)

Credit where it's due: this code is mostly from this blog post, it builds a function that will take two data frames and do what you need (taking values from the x data frame if they are present).

coalesce_join <- function(x, 
y,
by,
suffix = c(".x", ".y"),
join = dplyr::full_join, ...) {
joined <- join(x, y, by = by, suffix = suffix, ...)
# names of desired output
cols <- union(names(x), names(y))

to_coalesce <- names(joined)[!names(joined) %in% cols]
suffix_used <- suffix[ifelse(endsWith(to_coalesce, suffix[1]), 1, 2)]
# remove suffixes and deduplicate
to_coalesce <- unique(substr(
to_coalesce,
1,
nchar(to_coalesce) - nchar(suffix_used)
))

coalesced <- purrr::map_dfc(to_coalesce, ~dplyr::coalesce(
joined[[paste0(.x, suffix[1])]],
joined[[paste0(.x, suffix[2])]]
))
names(coalesced) <- to_coalesce

dplyr::bind_cols(joined, coalesced)[cols]
}


Related Topics



Leave a reply



Submit