提问人:Village.Idyot 提问时间:8/3/2023 更新时间:8/3/2023 访问量:39
如何对动态 R 列表中的嵌入数据帧列求和?
How sum embedded dataframe columns in a dynamic R list?
问:
我正在学习使用列表。
如何在具有嵌入式数据帧的动态列表中添加所有列,例如,我想对名称以 ?例如,在下面,函数或公式将返回一个向量 (7,9,11,13,15),表示子列表和子列表“First.allocation”列的列式和。First.allocation
Syria
List1
Syria_One
Syria_Two
再举一个例子,在下面,函数或公式将返回一个向量 (1,2,3,4,5),表示列表中唯一以“Syria”开头的子列表的列。List2
First.allocation
List1 <- list(
Syria_One = data.frame(
First.allocation = c(1,2,3,4,5),
Second.numerator = rep(0,5),
Second.allocation = rep(0,5)
),
Syria_Two = data.frame(
First.allocation = c(6,7,8,9,10),
Second.numerator = rep(0,5),
Second.allocation = rep(0,5)
),
Tunisia = data.frame(
First.allocation = rep(0.2,5),
Second.numerator = rep(0,5),
Second.allocation = rep(0,5)
),
Total = data.frame(
First.allocation = rep(1,5),
Second.numerator = rep(0,5),
Second.allocation = rep(0,5)
)
)
List2 <- list(
Syria_One = data.frame(
First.allocation = c(1,2,3,4,5),
Second.numerator = rep(0,5),
Second.allocation = rep(0,5)
),
Tunisia = data.frame(
First.allocation = rep(0.2,5),
Second.numerator = rep(0,5),
Second.allocation = rep(0,5)
),
Total = data.frame(
First.allocation = rep(1,5),
Second.numerator = rep(0,5),
Second.allocation = rep(0,5)
)
)
答:
2赞
jpsmith
8/3/2023
#1
可能有更优雅的方法,但一种方法是用于获取所需的列(用于隔离带有“Syria”的列),然后用于列,最后获得总和:lapply
grep
do.call
cbind
rowSums
rowSums(do.call(cbind, lapply(List1[grepl("Syria", names(List1))], function(x) x[,1])))
# [1] 7 9 11 13 15
为了分解这一点,因为上面的内容可能有点令人困惑:
syria <- grepl("Syria", names(List1))
# [1] TRUE TRUE FALSE FALSE
List_Syria <- List1[syria]
#$Syria_One
# First.allocation Second.numerator Second.allocation
#1 1 0 0
#2 2 0 0
#3 3 0 0
#4 4 0 0
#5 5 0 0
#
#$Syria_Two
# First.allocation Second.numerator Second.allocation
#1 6 0 0
#2 7 0 0
#3 8 0 0
#4 9 0 0
#5 10 0 0
test1 <- lapply(List_Syria, function(x) x[,1])
#$Syria_One
#[1] 1 2 3 4 5
#
#$Syria_Two
#[1] 6 7 8 9 10
test2 <- do.call(cbind, test1)
# Syria_One Syria_Two
#[1,] 1 6
#[2,] 2 7
#[3,] 3 8
#[4,] 4 9
#[5,] 5 10
rowSums(test2)
#[1] 7 9 11 13 15
3赞
Darren Tsai
8/3/2023
#2
为了动态地处理这个问题,你可以定义一个具有 2 个参数的函数:
regex
:列表名称的正则表达式col
:列名(或索引)
fun <- function(lst, regex = "^Syria", col = 1) {
Reduce(`+`, lapply(lst[grepl(regex, names(lst))], `[[`, col))
}
fun(List1)
# [1] 7 9 11 13 15
fun(List2)
# [1] 1 2 3 4 5
如果要操作除“Syria”以外的其他列表,或除“First.allocation”以外的其他列,可以在调用时修改这些参数。fun()
0赞
LMc
8/3/2023
#3
您可以对同名元素求和(其中类似命名表示最后一个元素之前的前缀):_
f <- function(l) {
split(names(l), gsub("_.*", "", names(l))) |>
lapply(\(x) Reduce(`+`, l[x]))
}
f(List1)
$Syria
First.allocation Second.numerator Second.allocation
1 7 0 0
2 9 0 0
3 11 0 0
4 13 0 0
5 15 0 0
$Total
First.allocation Second.numerator Second.allocation
1 1 0 0
2 1 0 0
3 1 0 0
4 1 0 0
5 1 0 0
$Tunisia
First.allocation Second.numerator Second.allocation
1 0.2 0 0
2 0.2 0 0
3 0.2 0 0
4 0.2 0 0
5 0.2 0 0
然后,您可以简单地访问所需的任何元素和列:
f(List1)$Syria$First.allocation
# [1] 7 9 11 13 15
如果您在同一列表中还有“Tunisia_One”和“Tunisia_Two”等,则这足够灵活。
评论