我有一个包含多个数据帧的列表。我想按类别(A
)对数据进行排序,并使用B
命令对频率(lapply
)求和。
数据为df_list
df_list
$`df.1`
A B
1 Apples 2
2 Pears 5
3 Apples 6
4 Pears 1
5 Apples 3
$`df.2`
A B
1 Oranges 2
2 Pineapples 5
3 Oranges 6
4 Pineapples 1
5 Oranges 3
所需的结果df_list_2看起来像这样:
df_list_2
$`df.1`
A B
1 Apples 11
2 Pears 6
$`df.2`
A B
1 Oranges 11
2 Pineapples 6
我已经基于lapply尝试了以下代码:
df_list_2<-df_list[, lapply(B, sum), by = A]
但是,我收到一个错误代码,说找不到A
。
在这种情况下,我可能会误认为lapply命令的工作方式,或者我对它应该如何工作的轻描淡写存在缺陷。 任何帮助表示赞赏。
答案 0 :(得分:4)
您需要在aggregate
中的lapply
lapply(df_list, function(x) aggregate(B~A, x, sum))
#[[1]]
# A B
#1 Apples 11
#2 Pears 6
#[[2]]
# A B
#1 Oranges 11
#2 Pineapples 6
使用map
和purrr
中的dplyr
library(dplyr)
purrr::map(df_list, ~.x %>% group_by(A) %>% summarise(sum = sum(B)))
数据
df_list <- list(structure(list(A = structure(c(1L, 2L, 1L, 2L, 1L),
.Label = c("Apples", "Pears"), class = "factor"), B = c(2L, 5L, 6L, 1L, 3L)),
class = "data.frame", row.names = c("1", "2", "3", "4", "5")),
structure(list(A = structure(c(1L, 2L, 1L, 2L, 1L), .Label = c("Oranges",
"Pineapples"), class = "factor"), B = c(2L, 5L, 6L, 1L, 3L)), class = "data.frame",
row.names = c("1", "2", "3", "4", "5")))
答案 1 :(得分:1)
我担心您可能对lapply
或提取操作符([
)都不了解。请记住,lapply(list, function)
将指定的function
应用于您赋予的list
的每个元素。提取为您提供您指定的元素:
x <- c('a', 'b', 'c')
x[2]
## "b"
我可以想象在R工作区的某个地方有一个对象名B
,这就是为什么您不会在
## Error in lapply(B, sum) : object 'B' not found
相反,如果您同时(有意或无意)定义了A
和B
,则会看到错误消息
## Error in df_list[, lapply(B, sum), by = A] : incorrect number of dimensions
因为根本就不是[
的使用方式;请记住,您只是将索引或布尔值与偶然的可选参数一起传递给[
,但是by
并不是其中之一。
因此,在没有进一步的前提下,这是我将如何执行此操作(在基数R中):
# make some data
a <- c(1, 2, 1, 2, 1)
b <- c(2, 5, 6, 1, 3)
df_list <- list(df.1 = data.frame(A = c('Apples', 'Pears')[a], B = b),
df.2 = data.frame(A = c('Oranges', 'Pineapples')[a], B = b))
# simplify it
df_list_2 <- lapply(df_list, function(x) {
aggregate(list(B = x$B), list(A = x$A), sum)
})
# the desired result
df_list_2
## $df.1
## A B
## 1 Apples 11
## 2 Pears 6
##
## $df.2
## A B
## 1 Oranges 11
## 2 Pineapples 6
您可以利用data.frame
只是一个列表这一事实,并缩短代码,如下所示:
df_list_2 <- lapply(df_list, function(x) {
aggregate(x['B'], x['A'], sum)
})
但是第一种书写方式应该有助于更清楚地了解我们在做什么
答案 2 :(得分:1)
OP帖子中的data.table
语法可以更改为
library(data.table)
lapply(df_list, function(x) as.data.table(x)[, .(B = sum(B)), by = A])
#$df.1
# A B
#1: Apples 11
#2: Pears 6
#$df.2
# A B
#1: Oranges 11
#2: Pineapples 6
df_list <- list(df.1 = structure(list(A = structure(c(1L, 2L, 1L, 2L, 1L
), .Label = c("Apples", "Pears"), class = "factor"), B = c(2L,
5L, 6L, 1L, 3L)), class = "data.frame", row.names = c("1", "2",
"3", "4", "5")), df.2 = structure(list(A = structure(c(1L, 2L,
1L, 2L, 1L), .Label = c("Oranges", "Pineapples"), class = "factor"),
B = c(2L, 5L, 6L, 1L, 3L)), class = "data.frame", row.names = c("1",
"2", "3", "4", "5")))