在不使用 for 的情况下过滤 R 中列表值的列表
Filtering list of list values in R without using for
我正在将循环 for()
操作转换为 apply()
系列操作:(sapply
、lapply
、mapply
等)以获得性能我所有的 R 代码。我有一个名为 lt
的列表列表,外观如下:
lt
$`11141550000`
y
2016-02-05 18
2016-03-03 8
2016-03-30 6
2016-04-26 0
$`11140780000`
y
2016-03-25 2
2016-03-30 0
2016-04-04 0
2016-04-09 0
2016-04-14 0
$`11141550000`
y
2016-02-05 18
2016-03-03 8
2016-07-16 10
2016-08-12 10
我的代码块非常慢(我知道 for
操作在 R 中效率不高,如果你想在这门语言中变得更专业,应该避免)。我在这样的块之前编码:
for (i in 1:length(lt)){
lt[[i]] <- lt[[i]][as.Date(index(lt[[i]]), format = "%Y-%m-%d") < "2018-11-01"]
}
我正在尝试将此 for
转换为快速 Filter
或 sapply
、lapply
操作,其中每个列表的每个值都必须在日期 "2018-11-01"
。尽管如此,我还没有能力:
第一次尝试:
f <- function(i){
lt[[i]][as.Date(index(lt[[i]]), format = "%Y-%m-%d") < "2018-11-01"]
}
lapply(lt, function(x) f(x))
但是收到错误:
Error in lt[[i]] : recursive indexing failed at level 2
第二次尝试:
f <- function(i){
lt[[i]][as.Date(index(lt[[i]]), format = "%Y-%m-%d") < "2018-11-01"]
}
Filter(function(x) f, lt)
但是我收到了这条消息:
Error in Filter(function(x) f, lt) :
(list) object cannot be coerced to type 'logical'
第三次尝试:
Filter(f, lt)
但是,我再次收到一个错误:
Error in lt[[i]] : recursive indexing failed at level 2
对于翻译此 for
操作的任何帮助,我将不胜感激,因为我需要更好地理解 apply
函数的动态。
P.D.1.
感谢 J.Gourlay 的反馈,我正在添加我的列表示例 dput
:
> dput(lt)
structure(list(`11140780000` = structure(c(2, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 4, 0, 0, 0, 0, 0, 0, 1
), .Dim = c(132L, 1L), .Dimnames = list(NULL, "y"), index = structure(c(1458864000,
1459296000, 1459728000, 1460160000, 1460592000, 1461024000, 1461456000,
1461888000, 1462320000, 1462752000, 1463184000, 1463616000, 1464048000,
1464480000, 1464912000, 1465344000, 1465776000, 1466208000, 1466640000,
1467072000, 1467504000, 1467936000, 1468368000, 1468800000, 1469232000,
1469664000, 1470096000, 1470528000, 1470960000, 1471392000, 1471824000,
1472256000, 1472688000, 1473120000, 1473552000, 1473984000, 1474416000,
1474848000, 1475280000, 1475712000, 1476144000, 1476576000, 1477008000,
1477440000, 1477872000, 1478304000, 1478736000, 1479168000, 1479600000,
1480032000, 1480464000, 1480896000, 1481328000, 1481760000, 1482192000,
1482624000, 1483056000, 1483142400, 1483574400, 1484006400, 1484438400,
1484870400, 1485302400, 1485734400, 1486166400, 1486598400, 1487030400,
1487462400, 1487894400, 1488326400, 1488758400, 1489190400, 1489622400,
1490054400, 1490486400, 1490918400, 1491350400, 1491782400, 1492214400,
1492646400, 1493078400, 1493510400, 1493942400, 1494374400, 1494806400,
1495238400, 1495670400, 1496102400, 1496534400, 1496966400, 1497398400,
1497830400, 1498262400, 1498694400, 1499126400, 1499558400, 1499990400,
1500422400, 1500854400, 1501286400, 1501718400, 1502150400, 1502582400,
1503014400, 1503446400, 1503878400, 1504310400, 1504742400, 1505174400,
1505606400, 1506038400, 1506470400, 1506902400, 1507334400, 1507766400,
1508198400, 1508630400, 1509062400, 1509494400, 1509926400, 1510358400,
1510790400, 1511222400, 1511654400, 1512086400, 1512518400, 1512950400,
1513382400, 1513814400, 1514246400, 1514678400, 1514764800), tzone = "UTC", tclass = "Date"), .indexCLASS = "Date", .indexTZ = "UTC", tclass = "Date", tzone = "UTC", class = c("xts",
"zoo")), `11141550000` = structure(c(18, 8, 6, 0, 4, 8, 10, 10,
0, 23, 0, 8, 0, 2, 14, 16, 20, 4, 4, 4), .indexCLASS = "Date", .indexTZ = "UTC", tclass = "Date", tzone = "UTC", class = c("xts",
"zoo"), index = structure(c(1454630400, 1456963200, 1459296000,
1461628800, 1463961600, 1466294400, 1468627200, 1470960000, 1473292800,
1475625600, 1477958400, 1480291200, 1482624000, 1483142400, 1483833600,
1486166400, 1488499200, 1490832000, 1493164800, 1495497600), tzone = "UTC", tclass = "Date"), .Dim = c(20L,
1L), .Dimnames = list(NULL, "y"))), .Names = c("11140780000",
"11141550000"))
P.D.2.
根据 Jozef 的建议,我确认我已使用库 zoo
来重现我的代码。 IE。 for
循环中 zoo
包的函数 index
。
本质上,您传递的对象需要 lapply
中的整数索引。考虑在 seq_along(lt)
中包装 lt 作为 lapply
的输入。另外,请记住与 for
循环不同,apply 函数 return 对象。因此将 lapply
分配给一个对象。此外,当函数接受一个非可选参数时,无需指定 function
运算符。
f <- function(i){
lt[[i]][as.Date(index(lt[[i]]), format = "%Y-%m-%d") < "2018-11-01"]
}
new_lt <- lapply(seq_along(lt), f)
如果您的 for
循环如您所说,new_lt 应该与 lt 完全相同在 运行 for
循环之后:
all.equal(lt_after_for_loop, new_lt)
# [1] TRUE
identical(lt_after_for_loop, new_lt)
# [1] TRUE
或者,传递整个对象而不是使用调整后定义函数的索引:
f <- function(obj){
obj[as.Date(index(obj), format = "%Y-%m-%d") < "2018-11-01"]
}
new_lt <- lapply(lt, f)
最后,Filter()
用于按逻辑条件过滤(保留或删除)列表的对象,而不是列表的每个项目中的内容,除非您使用此类内部内容来决定顶级项目是从列表中删除。但是 for
和 lapply
在处理过程中不排除项目(即相同数量的项目 before/after 他们的调用)。
我正在将循环 for()
操作转换为 apply()
系列操作:(sapply
、lapply
、mapply
等)以获得性能我所有的 R 代码。我有一个名为 lt
的列表列表,外观如下:
lt
$`11141550000`
y
2016-02-05 18
2016-03-03 8
2016-03-30 6
2016-04-26 0
$`11140780000`
y
2016-03-25 2
2016-03-30 0
2016-04-04 0
2016-04-09 0
2016-04-14 0
$`11141550000`
y
2016-02-05 18
2016-03-03 8
2016-07-16 10
2016-08-12 10
我的代码块非常慢(我知道 for
操作在 R 中效率不高,如果你想在这门语言中变得更专业,应该避免)。我在这样的块之前编码:
for (i in 1:length(lt)){
lt[[i]] <- lt[[i]][as.Date(index(lt[[i]]), format = "%Y-%m-%d") < "2018-11-01"]
}
我正在尝试将此 for
转换为快速 Filter
或 sapply
、lapply
操作,其中每个列表的每个值都必须在日期 "2018-11-01"
。尽管如此,我还没有能力:
第一次尝试:
f <- function(i){
lt[[i]][as.Date(index(lt[[i]]), format = "%Y-%m-%d") < "2018-11-01"]
}
lapply(lt, function(x) f(x))
但是收到错误:
Error in lt[[i]] : recursive indexing failed at level 2
第二次尝试:
f <- function(i){
lt[[i]][as.Date(index(lt[[i]]), format = "%Y-%m-%d") < "2018-11-01"]
}
Filter(function(x) f, lt)
但是我收到了这条消息:
Error in Filter(function(x) f, lt) :
(list) object cannot be coerced to type 'logical'
第三次尝试:
Filter(f, lt)
但是,我再次收到一个错误:
Error in lt[[i]] : recursive indexing failed at level 2
对于翻译此 for
操作的任何帮助,我将不胜感激,因为我需要更好地理解 apply
函数的动态。
P.D.1.
感谢 J.Gourlay 的反馈,我正在添加我的列表示例 dput
:
> dput(lt)
structure(list(`11140780000` = structure(c(2, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 4, 0, 0, 0, 0, 0, 0, 1
), .Dim = c(132L, 1L), .Dimnames = list(NULL, "y"), index = structure(c(1458864000,
1459296000, 1459728000, 1460160000, 1460592000, 1461024000, 1461456000,
1461888000, 1462320000, 1462752000, 1463184000, 1463616000, 1464048000,
1464480000, 1464912000, 1465344000, 1465776000, 1466208000, 1466640000,
1467072000, 1467504000, 1467936000, 1468368000, 1468800000, 1469232000,
1469664000, 1470096000, 1470528000, 1470960000, 1471392000, 1471824000,
1472256000, 1472688000, 1473120000, 1473552000, 1473984000, 1474416000,
1474848000, 1475280000, 1475712000, 1476144000, 1476576000, 1477008000,
1477440000, 1477872000, 1478304000, 1478736000, 1479168000, 1479600000,
1480032000, 1480464000, 1480896000, 1481328000, 1481760000, 1482192000,
1482624000, 1483056000, 1483142400, 1483574400, 1484006400, 1484438400,
1484870400, 1485302400, 1485734400, 1486166400, 1486598400, 1487030400,
1487462400, 1487894400, 1488326400, 1488758400, 1489190400, 1489622400,
1490054400, 1490486400, 1490918400, 1491350400, 1491782400, 1492214400,
1492646400, 1493078400, 1493510400, 1493942400, 1494374400, 1494806400,
1495238400, 1495670400, 1496102400, 1496534400, 1496966400, 1497398400,
1497830400, 1498262400, 1498694400, 1499126400, 1499558400, 1499990400,
1500422400, 1500854400, 1501286400, 1501718400, 1502150400, 1502582400,
1503014400, 1503446400, 1503878400, 1504310400, 1504742400, 1505174400,
1505606400, 1506038400, 1506470400, 1506902400, 1507334400, 1507766400,
1508198400, 1508630400, 1509062400, 1509494400, 1509926400, 1510358400,
1510790400, 1511222400, 1511654400, 1512086400, 1512518400, 1512950400,
1513382400, 1513814400, 1514246400, 1514678400, 1514764800), tzone = "UTC", tclass = "Date"), .indexCLASS = "Date", .indexTZ = "UTC", tclass = "Date", tzone = "UTC", class = c("xts",
"zoo")), `11141550000` = structure(c(18, 8, 6, 0, 4, 8, 10, 10,
0, 23, 0, 8, 0, 2, 14, 16, 20, 4, 4, 4), .indexCLASS = "Date", .indexTZ = "UTC", tclass = "Date", tzone = "UTC", class = c("xts",
"zoo"), index = structure(c(1454630400, 1456963200, 1459296000,
1461628800, 1463961600, 1466294400, 1468627200, 1470960000, 1473292800,
1475625600, 1477958400, 1480291200, 1482624000, 1483142400, 1483833600,
1486166400, 1488499200, 1490832000, 1493164800, 1495497600), tzone = "UTC", tclass = "Date"), .Dim = c(20L,
1L), .Dimnames = list(NULL, "y"))), .Names = c("11140780000",
"11141550000"))
P.D.2.
根据 Jozef 的建议,我确认我已使用库 zoo
来重现我的代码。 IE。 for
循环中 zoo
包的函数 index
。
本质上,您传递的对象需要 lapply
中的整数索引。考虑在 seq_along(lt)
中包装 lt 作为 lapply
的输入。另外,请记住与 for
循环不同,apply 函数 return 对象。因此将 lapply
分配给一个对象。此外,当函数接受一个非可选参数时,无需指定 function
运算符。
f <- function(i){
lt[[i]][as.Date(index(lt[[i]]), format = "%Y-%m-%d") < "2018-11-01"]
}
new_lt <- lapply(seq_along(lt), f)
如果您的 for
循环如您所说,new_lt 应该与 lt 完全相同在 运行 for
循环之后:
all.equal(lt_after_for_loop, new_lt)
# [1] TRUE
identical(lt_after_for_loop, new_lt)
# [1] TRUE
或者,传递整个对象而不是使用调整后定义函数的索引:
f <- function(obj){
obj[as.Date(index(obj), format = "%Y-%m-%d") < "2018-11-01"]
}
new_lt <- lapply(lt, f)
最后,Filter()
用于按逻辑条件过滤(保留或删除)列表的对象,而不是列表的每个项目中的内容,除非您使用此类内部内容来决定顶级项目是从列表中删除。但是 for
和 lapply
在处理过程中不排除项目(即相同数量的项目 before/after 他们的调用)。