使用列值作为列表数据帧中的数据帧索引(Map 或 lapply with seq_along)?
Using column value as dataframe index in list dataframes (Map or lapply with seq_along)?
我有一个数据框列表 list1
,每个数据框中需要一个新列 'mn',它是基于另一列中的值的条件列数的平均值 num
加一。因此,对于 num=3
,新列将是前四列的平均值。对于下面的例子
df1 <- data.frame(num= c(3, 1, 1, 1, 2), d1= c(1, 17, 17, 17, 15), d2= c(1, 15, 15, 15, 21), d3= c(6, 21, 21, 21, 23), d4= c(2, 3, 3, 3, 2))
df2 <- data.frame(num= c(3, 2, 2, 2, 2), d1= c(1, 10, 10, 10, 15), d2= c(1, 5, 5, 5, 21), d3= c(6, 2, 2, 2, 23), d4= c(2, 3, 3, 3, 5))
list1 <- list(df1, df2)
我希望
newlist
[[1]]
num d1 d2 d3 d4 mn
1 3 1 1 6 2 2.5
2 1 17 15 21 3 16.0
3 1 17 15 21 3 16.0
我得到的最接近的是
newlist <- lapply(list1, function(x) {
x <- cbind(x, sapply(x$num, function(y) {
y <- rowSums(x[2:(2+y)])/(y+1)
}))
})
为每一行的平均值绑定列。基于 我想我需要一个 seq_along 或内部函数上的一个 Map 但我不知道如何实现它。
一个选项是用 lapply
遍历 list
,根据 'num' 列值(+ 1), 获取 mean
并在 transform
中创建新列
lapply(list1, function(x) transform(x,
mn = apply(x, 1, function(y) mean(y[-1][seq(y[1]+1)]))))
#[[1]]
# num d1 d2 d3 d4 mn
#1 3 1 1 6 2 2.50000
#2 1 17 15 21 3 16.00000
#3 1 17 15 21 3 16.00000
#4 1 17 15 21 3 16.00000
#5 2 15 21 23 2 19.66667
#[[2]]
# num d1 d2 d3 d4 mn
#1 3 1 1 6 2 2.500000
#2 2 10 5 2 3 5.666667
#3 2 10 5 2 3 5.666667
#4 2 10 5 2 3 5.666667
#5 2 15 21 23 5 19.666667
或使用 tidyverse
,通过使用 pivot_longer
转换为 'long' 格式,逐行进行分组并获得第一个 'n' 的 mean
基于 'num' 值
的元素
library(purrr)
library(dplyr)
library(tidyr)
map(list1, ~
.x %>%
mutate(rn = row_number()) %>%
pivot_longer(cols = starts_with('d')) %>%
group_by(rn) %>%
summarise(value = mean(value[seq_len(first(num) + 1)])) %>%
pull(value) %>%
bind_cols(.x, mn = .))
我有一个数据框列表 list1
,每个数据框中需要一个新列 'mn',它是基于另一列中的值的条件列数的平均值 num
加一。因此,对于 num=3
,新列将是前四列的平均值。对于下面的例子
df1 <- data.frame(num= c(3, 1, 1, 1, 2), d1= c(1, 17, 17, 17, 15), d2= c(1, 15, 15, 15, 21), d3= c(6, 21, 21, 21, 23), d4= c(2, 3, 3, 3, 2))
df2 <- data.frame(num= c(3, 2, 2, 2, 2), d1= c(1, 10, 10, 10, 15), d2= c(1, 5, 5, 5, 21), d3= c(6, 2, 2, 2, 23), d4= c(2, 3, 3, 3, 5))
list1 <- list(df1, df2)
我希望
newlist
[[1]]
num d1 d2 d3 d4 mn
1 3 1 1 6 2 2.5
2 1 17 15 21 3 16.0
3 1 17 15 21 3 16.0
我得到的最接近的是
newlist <- lapply(list1, function(x) {
x <- cbind(x, sapply(x$num, function(y) {
y <- rowSums(x[2:(2+y)])/(y+1)
}))
})
为每一行的平均值绑定列。基于
一个选项是用 lapply
遍历 list
,根据 'num' 列值(+ 1), 获取 mean
并在 transform
lapply(list1, function(x) transform(x,
mn = apply(x, 1, function(y) mean(y[-1][seq(y[1]+1)]))))
#[[1]]
# num d1 d2 d3 d4 mn
#1 3 1 1 6 2 2.50000
#2 1 17 15 21 3 16.00000
#3 1 17 15 21 3 16.00000
#4 1 17 15 21 3 16.00000
#5 2 15 21 23 2 19.66667
#[[2]]
# num d1 d2 d3 d4 mn
#1 3 1 1 6 2 2.500000
#2 2 10 5 2 3 5.666667
#3 2 10 5 2 3 5.666667
#4 2 10 5 2 3 5.666667
#5 2 15 21 23 5 19.666667
或使用 tidyverse
,通过使用 pivot_longer
转换为 'long' 格式,逐行进行分组并获得第一个 'n' 的 mean
基于 'num' 值
library(purrr)
library(dplyr)
library(tidyr)
map(list1, ~
.x %>%
mutate(rn = row_number()) %>%
pivot_longer(cols = starts_with('d')) %>%
group_by(rn) %>%
summarise(value = mean(value[seq_len(first(num) + 1)])) %>%
pull(value) %>%
bind_cols(.x, mn = .))