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 inhumanlist
, butNud5
not in ratlistSdhb
is found inratlist
, butSDHB1
not in humanlist- Some gene names are not found in both the lists
- Here, only
Dok10
andDOCK10
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
Warning: Unable to Access Index for Repository Https://Www.Stats.Ox.Ac.Uk/Pub/Rwin/Src/Contrib:
How to Insert Pictures into Each Individual Bar in a Ggplot Graph
Export All User Inputs in a Shiny App to File and Load Them Later
How Can a Script Find Itself in R Running from the Command Line
Check If R Package Is Installed Then Load Library
How to Store R Ggplot Graph as HTML Code Snippet
Fama MACbeth Standard Errors in R
Xpath to Extract Text After Br Tags in R
How to Select All Unique Combinations of Two Columns in an R Data Frame
How to Use Aws Cli to Only Copy Files in S3 Bucket That Match a Given String Pattern
Data.Table VS Plyr Regression Output
Get the Last Row of a Previous Group in Data.Table
Subset Data Based on Partial Match of Column Names