将具有未命名条目的列表列表转换为数据框或 tibble
Turn a list of lists with unnamed entries into a data frame or a tibble
我正在使用来自 RStudio 的 reticulate
R 包到 运行 一些 python 代码将数据从 ROOT (http://root.cern.ch) 导入 R。我的问题是python 代码 return 是一个按行列表的列表。例如,在 python、
[[0L, 0L, 'mu+', 1, 0, 0, 1, 3231.6421853545253, -17.361063509909364, 6322.884067996471, -2751.857298366544, 1.2318766603937736, 1407.9560948453036, 3092.931322317615],
[0L, 0L, 'nu_e', 3, 1, 0, 0, 3231.6421853545253, -17.361063509909364, 6322.884067996471, -743.6755000649275, 9.950229845741603, 342.4203222294634, 818.781981693865],
[0L, 0L, 'anti_nu_mu', 2, 1, 0, 0, 3231.6421853545253, -17.361063509909364, 6322.884067996471, -808.1114666690765, 21.680955968349267, 445.2784282520303, 922.9231198102832],
...]
这些数据被 reticulate
、
转化为 R 中相应的列表列表
List of 136972
$ :List of 14
..$ : int 0
..$ : int 0
..$ : chr "mu+"
..$ : int 1
..$ : int 0
..$ : int 0
..$ : int 0
..$ : num 7162
..$ : num -0.0108
..$ : num -627
..$ : num 264
..$ : num -3.24
..$ : num 3080
..$ : num 3093
$ :List of 14
..$ : int 0
..$ : int 0
..$ : chr "mu+"
..$ : int 1
.... (you get the idea)
我找遍了所有我能想到的地方,但我找不到将这些数据变成数据框的方法(我真的很想要一个tibble)。一个问题似乎是列表条目未命名。有很多数据,所以我不想做一些低效的事情。我可以使用 python 代码 return 列字典,这将起作用。但是 python 生成一行的代码要简单得多。
如果有一种简单的方法可以将这些按行列表转换为数据框,那就太理想了。有什么想法吗?
想到以下几种方法:
选项 1:我们知道子列表中有多少项(预期有多少列)。循环列表以使用子列表中的每个相关元素创建一个新列表。将其包裹在 as.data.frame
中,您就完成了。
myFun_1 <- function(inlist, expectedCols = 14) {
as.data.frame(
lapply(sequence(expectedCols),
function(x) {
sapply(inlist, function(y) y[[x]])
}),
col.names = paste0("V", sequence(expectedCols)))
}
选项 2。使用 do.call(rbind, .)
,然后使用 unlist
每列来制作一个没有 list
列的常规 data.frame
。
myFun_2 <- function(inlist) {
x <- as.data.frame(do.call(rbind, inlist))
x[] <- lapply(x, unlist)
x
}
让我们用一些示例数据来测试这些。这是一个 list
应该创建一个矩形的 3 行 x 14 列数据集:
LL <- list(
list(0L, 0L, 'mu+', 1, 0, 0, 1, 3231.6421853545253, -17.361063509909364,
6322.884067996471, -2751.857298366544, 1.2318766603937736,
1407.9560948453036, 3092.931322317615),
list(0L, 0L, 'nu_e', 3, 1, 0, 0, 3231.6421853545253, -17.361063509909364,
6322.884067996471, -743.6755000649275, 9.950229845741603,
342.4203222294634, 818.781981693865),
list(0L, 0L, 'anti_nu_mu', 2, 1, 0, 0, 3231.6421853545253,
-17.361063509909364, 6322.884067996471, -808.1114666690765,
21.680955968349267, 445.2784282520303, 922.9231198102832))
这是一个更大的版本,它将创建一个 150000 行乘 14 列的数据集。
Big_LL <- unlist(replicate(50000, LL, FALSE), FALSE)
每个函数在小数据集上的结果:
myFun_1(LL)
## V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12
## 1 0 0 mu+ 1 0 0 1 3231.642 -17.36106 6322.884 -2751.8573 1.231877
## 2 0 0 nu_e 3 1 0 0 3231.642 -17.36106 6322.884 -743.6755 9.950230
## 3 0 0 anti_nu_mu 2 1 0 0 3231.642 -17.36106 6322.884 -808.1115 21.680956
## V13 V14
## 1 1407.9561 3092.9313
## 2 342.4203 818.7820
## 3 445.2784 922.9231
myFun_2(LL)
## V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12
## 1 0 0 mu+ 1 0 0 1 3231.642 -17.36106 6322.884 -2751.8573 1.231877
## 2 0 0 nu_e 3 1 0 0 3231.642 -17.36106 6322.884 -743.6755 9.950230
## 3 0 0 anti_nu_mu 2 1 0 0 3231.642 -17.36106 6322.884 -808.1115 21.680956
## V13 V14
## 1 1407.9561 3092.9313
## 2 342.4203 818.7820
## 3 445.2784 922.9231
看起来都不错。现在,性能如何?
system.time(myFun_1(Big_LL))
## user system elapsed
## 2.65 0.05 2.75
system.time(myFun_2(Big_LL))
## user system elapsed
## 0.41 0.00 0.40
所以,采用第二种方法 ;-)
我正在使用来自 RStudio 的 reticulate
R 包到 运行 一些 python 代码将数据从 ROOT (http://root.cern.ch) 导入 R。我的问题是python 代码 return 是一个按行列表的列表。例如,在 python、
[[0L, 0L, 'mu+', 1, 0, 0, 1, 3231.6421853545253, -17.361063509909364, 6322.884067996471, -2751.857298366544, 1.2318766603937736, 1407.9560948453036, 3092.931322317615],
[0L, 0L, 'nu_e', 3, 1, 0, 0, 3231.6421853545253, -17.361063509909364, 6322.884067996471, -743.6755000649275, 9.950229845741603, 342.4203222294634, 818.781981693865],
[0L, 0L, 'anti_nu_mu', 2, 1, 0, 0, 3231.6421853545253, -17.361063509909364, 6322.884067996471, -808.1114666690765, 21.680955968349267, 445.2784282520303, 922.9231198102832],
...]
这些数据被 reticulate
、
List of 136972
$ :List of 14
..$ : int 0
..$ : int 0
..$ : chr "mu+"
..$ : int 1
..$ : int 0
..$ : int 0
..$ : int 0
..$ : num 7162
..$ : num -0.0108
..$ : num -627
..$ : num 264
..$ : num -3.24
..$ : num 3080
..$ : num 3093
$ :List of 14
..$ : int 0
..$ : int 0
..$ : chr "mu+"
..$ : int 1
.... (you get the idea)
我找遍了所有我能想到的地方,但我找不到将这些数据变成数据框的方法(我真的很想要一个tibble)。一个问题似乎是列表条目未命名。有很多数据,所以我不想做一些低效的事情。我可以使用 python 代码 return 列字典,这将起作用。但是 python 生成一行的代码要简单得多。
如果有一种简单的方法可以将这些按行列表转换为数据框,那就太理想了。有什么想法吗?
想到以下几种方法:
选项 1:我们知道子列表中有多少项(预期有多少列)。循环列表以使用子列表中的每个相关元素创建一个新列表。将其包裹在
as.data.frame
中,您就完成了。myFun_1 <- function(inlist, expectedCols = 14) { as.data.frame( lapply(sequence(expectedCols), function(x) { sapply(inlist, function(y) y[[x]]) }), col.names = paste0("V", sequence(expectedCols))) }
选项 2。使用
do.call(rbind, .)
,然后使用unlist
每列来制作一个没有list
列的常规data.frame
。myFun_2 <- function(inlist) { x <- as.data.frame(do.call(rbind, inlist)) x[] <- lapply(x, unlist) x }
让我们用一些示例数据来测试这些。这是一个 list
应该创建一个矩形的 3 行 x 14 列数据集:
LL <- list(
list(0L, 0L, 'mu+', 1, 0, 0, 1, 3231.6421853545253, -17.361063509909364,
6322.884067996471, -2751.857298366544, 1.2318766603937736,
1407.9560948453036, 3092.931322317615),
list(0L, 0L, 'nu_e', 3, 1, 0, 0, 3231.6421853545253, -17.361063509909364,
6322.884067996471, -743.6755000649275, 9.950229845741603,
342.4203222294634, 818.781981693865),
list(0L, 0L, 'anti_nu_mu', 2, 1, 0, 0, 3231.6421853545253,
-17.361063509909364, 6322.884067996471, -808.1114666690765,
21.680955968349267, 445.2784282520303, 922.9231198102832))
这是一个更大的版本,它将创建一个 150000 行乘 14 列的数据集。
Big_LL <- unlist(replicate(50000, LL, FALSE), FALSE)
每个函数在小数据集上的结果:
myFun_1(LL)
## V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12
## 1 0 0 mu+ 1 0 0 1 3231.642 -17.36106 6322.884 -2751.8573 1.231877
## 2 0 0 nu_e 3 1 0 0 3231.642 -17.36106 6322.884 -743.6755 9.950230
## 3 0 0 anti_nu_mu 2 1 0 0 3231.642 -17.36106 6322.884 -808.1115 21.680956
## V13 V14
## 1 1407.9561 3092.9313
## 2 342.4203 818.7820
## 3 445.2784 922.9231
myFun_2(LL)
## V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12
## 1 0 0 mu+ 1 0 0 1 3231.642 -17.36106 6322.884 -2751.8573 1.231877
## 2 0 0 nu_e 3 1 0 0 3231.642 -17.36106 6322.884 -743.6755 9.950230
## 3 0 0 anti_nu_mu 2 1 0 0 3231.642 -17.36106 6322.884 -808.1115 21.680956
## V13 V14
## 1 1407.9561 3092.9313
## 2 342.4203 818.7820
## 3 445.2784 922.9231
看起来都不错。现在,性能如何?
system.time(myFun_1(Big_LL))
## user system elapsed
## 2.65 0.05 2.75
system.time(myFun_2(Big_LL))
## user system elapsed
## 0.41 0.00 0.40
所以,采用第二种方法 ;-)