R:在嵌套列表中交换2个值

时间:2016-10-03 15:07:17

标签: r

[[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

假设我有2个嵌套列表,如上所示,我正在寻找能够在列表中更新(例如46)的功能,其中包含列表中的其他数字(比如92)和更新92' s与46而不改变列表的结构

预期输出将是这样的

[[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库具有list.find / list.findi等函数,仅适用于命名嵌套列表。我不是一个名单

2 个答案:

答案 0 :(得分:2)

这可能是一个简单的rapply吗?请参阅此示例,其中46由92 替换(反过来,由@akrun添加)

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

how = "list"确保您恢复原始结构。

答案 1 :(得分:2)

这是实现这一目标的另一种方式。首先,您只需将列表转换为矢量(unlist(l))。进行必要的交换并将其转换回列表(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)

<强>基准

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

规模更大

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

很明显,f_m0h3nf_jakub效果更好。对于较大的尺度,差异甚至更显着(时间减少了近一半)。