2016-10-03 16 views
3
[[1]] 
[[1]][[1]] 
[1] 1 46 107 69 1 

[[1]][[2]] 
[1] 1 146 145 71 92 1 
#################### 
[[2]] 
[[2]][[1]] 
[1] 1 46 18 92 1 

[[2]][[2]] 
[1] 1 127 145 53 168 1 

Angenommen I 2 verschachtelte Liste habe, wie oben gezeigt, ich bin auf der Suche nach Funktion, wo ich die Liste sowohl aktualisieren kann in der Liste mit einer anderen Zahl in (etwa 46) (sagen 92) und Update 92 ist mit 46, ohne die Struktur der Liste zu verändernR: Vertauschen von 2 Werten in einer verschachtelten Liste

Erwartete Ausgabe etwas sein wird, wie diese

[[1]] 
[[1]][[1]] 
[1] 1 92 107 69 1 

[[1]][[2]] 
[1] 1 146 145 71 46 1 
#### 
[[2]] 
[[2]][[1]] 
[1] 1 92 18 46 1 

[[2]][[2]] 
[1] 1 127 145 53 168 1 

Rlist Bibliothek verfügt über Funktionen wie List.Find/list.findi, die nur funktioniert für benannte verschachtelte Liste. Mine ist keine benannte Liste

Antwort

2

Dies ist eine andere Möglichkeit, das zu erreichen. Zuerst konvertieren Sie einfach Ihre Liste in Vektor (unlist(l)). Führen Sie Ihre notwendigen Swaps aus und konvertieren Sie sie zurück in Ihre Liste (relist(x, skeleton = l)).

x <- unlist(l) 
a <- which(x==46) 
b <- which(x==92) 
x[a] <- 92 
x[b] <- 46 
relist(x, skeleton = l) 

Benchmarking

library(microbenchmark) 
l <- list(list(c(1, 46, 107, 69, 1), c(1, 146, 145, 71, 92, 1)), list(
    c(1, 46, 18, 92, 1), c(1, 127, 145, 53, 168, 1))) 

f_m0h3n <- function(l){x <- unlist(l);a <- which(x==46);b <- which(x==92);x[a] <- 92;x[b] <- 46;relist(x, l);} 
f_jakub <- function(li) rapply(li, function(x) ifelse(x == 46, 92,ifelse(x==92, 46, x)), how = "list") 
all.equal(f_m0h3n(l), f_jakub(l)) 
# [1] TRUE 
microbenchmark(f_m0h3n(l), f_jakub(l)) 

# Unit: microseconds 
     # expr  min  lq  mean median  uq  max neval 
# f_m0h3n(l) 100.942 103.509 109.7108 107.3580 111.6355 204.879 100 
# f_jakub(l) 126.178 131.738 142.8850 137.9405 143.7150 357.148 100 

Größere Skala

library(microbenchmark) 
set.seed(123) 
l <- list(list(sample(1000), sample(2000)),list(sample(1000), sample(2000))) 

all.equal(f_m0h3n(l), f_jakub(l)) 
# [1] TRUE 
microbenchmark(f_m0h3n(l), f_jakub(l)) 

# Unit: microseconds 
     # expr  min  lq  mean median  uq  max neval 
# f_m0h3n(l) 588.973 615.0645 896.9371 651.2065 692.268 2827.242 100 
# f_jakub(l) 1022.683 1053.9070 1914.0769 1253.0115 2848.842 3287.898 100 

Es ist offensichtlich, dass f_m0h3n funktioniert besser als f_jakub. Der Unterschied ist für größere Skalen noch signifikanter (die Zeit wird fast um die Hälfte reduziert).

+2

das ist eine interessante Art der Auflistung und Wiederveröffentlichung. Danke fürs Teilen – Eswar

+1

danke für 'relist', ich wusste nicht, dass es existiert! – jakub

2

Könnte es eine einfache rapply sein? Sehen Sie dieses Beispiel, wo 46 von 92 ersetzt wird (und umgekehrt, wie @akrun hinzugefügt):

li = list(list(c(1, 46, 107, 69, 1), 
       c(1, 146, 145, 71, 92, 1))) 
# [[1]] 
# [[1]][[1]] 
# [1] 1 46 107 69 1 
# 
# [[1]][[2]] 
# [1] 1 146 145 71 92 1 

rapply(li, function(x) ifelse(x == 46, 92,ifelse(x==92, 46, x)), how = "list") 

# [[1]] 
# [[1]][[1]] 
# [1] 1 92 107 69 1 
# 
# [[1]][[2]] 
# [1] 1 146 145 71 46 1 

Die how = "list" stellt sicher, dass Sie die ursprüngliche Struktur zurück.

+0

Ich denke, die 92 im zweiten Listenelement sollte in 42 geändert werden. Vielleicht 'rapply (li, Funktion (x) ifelse (x == 46, 92, ifelse (x == 92, 46, x)), how = "list") ' – akrun

+1

Sie haben Recht. Hinzugefügt. – jakub

+0

Coole Jungs !!! Es klappt. Danke für die Hilfe . – Eswar

Verwandte Themen