[英]Using lapply to group list of data frames by column
我有一個包含多個數據框的列表。 我想按類別( A
)對數據進行排序,並使用lapply
-命令對頻率( B
)求和。
數據是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 命令在這種情況下的工作方式,要么我對它應該如何工作的低估是有缺陷的。 非常感謝任何幫助。
你需要在lapply
中aggregate
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
和dplyr
的purrr
將是
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")))
我擔心您可能對lapply
或提取運算符 ( [
) 不清楚。 請記住lapply(list, function)
將指定的function
應用於您給它的list
的每個元素。 Extract 為您提供您指定的元素:
x <- c('a', 'b', 'c')
x[2]
## "b"
我想在您的 R 工作區的某個地方,您有一個 object 名稱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)
})
但第一種寫法應該有助於更清楚地說明我們在做什么
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")))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.