我有一个数据表my_table
,其中包含数字,字符和日期(POSIXct
)列。现在我需要aggregate
按日期,每个日期的数字列应由mean
汇总,字符和日期列只有一个可用的值(让我们说第一次出现)。我是这样的:
name date value
"test" 2018-04-04 1
"test" 2018-04-04 2
"test" 2018-04-05 8
"test" 2018-04-06 3
我希望有这个:
name date value
"test" 2018-04-04 1.5
"test" 2018-04-05 8.0
"test" 2018-04-06 3.0
我的方法是:
new_table <- aggregate(my_table, by=list(my_table$date), FUN=mean)
导致:
name date value
NA 2018-04-04 1.5
NA 2018-04-05 8.0
NA 2018-04-06 3.0
和一堆警告,因为name
不是数字。我怎么能告诉函数只使用"test"
而不是name
的{{1}}出现的一个(或者第一个,我不介意)?
让事情变得更难:在我的实际情况中,实际上有很多列需要使用均值(如果它们是数字)或第一次出现(如果它们是NA
或character
)。
答案 0 :(得分:1)
使用aggregate
的基础R解决方案:
df <- transform(df, date = as.POSIXct(date))
aggregate(value ~ date + name, data = df, FUN = mean);
#date name value
#1 2018-04-04 test 1.5
#2 2018-04-05 test 8.0
#3 2018-04-06 test 3.0
如果您有许多列不想明确列出,可以使用:
aggregate(value ~ ., data = df, FUN = mean);
.
表示df
中的所有列,但 value
除外。
tidyverse
解决方案使用group_by
和summarise
:
library(tidyverse)
df %>%
mutate(date = as.POSIXct(date)) %>%
group_by(date, name) %>%
summarise(value = mean(value))
## A tibble: 3 x 3
## Groups: date [?]
# date name value
# <dttm> <fct> <dbl>
#1 2018-04-04 00:00:00 test 1.50
#2 2018-04-05 00:00:00 test 8.00
#3 2018-04-06 00:00:00 test 3.00
你的标题有点误导:为什么“不同的功能”?我假设你的意思是不同的列。如果您 要求汇总应用不同的功能,您可以执行以下操作:
aggregate(value ~ date + name, data = df, FUN = function(x) c(mean = mean(x), sd = sd(x)));
# date name value.mean value.sd
#1 2018-04-04 test 1.5000000 0.7071068
#2 2018-04-05 test 8.0000000 NA
#3 2018-04-06 test 3.0000000 NA
df <- read.table(text =
" name date value
test 2018-04-04 1
test 2018-04-04 2
test 2018-04-05 8
test 2018-04-06 3", header = T)
答案 1 :(得分:1)
您可以根据变量定义自己的汇总函数来执行您想要的操作。类
my_table <- read.table(text =
" name date value
test 2018-04-04 1
test 2018-04-04 2
test 2018-04-05 8
test 2018-04-06 3",
header = T)
my_summarise <- function(x){
if(is.numeric(x)) mean(x)
else if(is.character(x)) x[1]
else if(is.factor(x)) x[1]
else if('POSIXct' %in% class(x)) x[1]
}
setDT(my_table)
my_table[, lapply(.SD, my_summarise), by = date]
# date name value
# 1: 2018-04-04 test 1.5
# 2: 2018-04-05 test 8.0
# 3: 2018-04-06 test 3.0
编辑:实际上没有必要。您可以这样做以获得相同的结果。
my_table[, .(name, mean(value)), by = date]
答案 2 :(得分:0)
如果您实际上使用的是data.table
,那么这就是聚合列的简便方法。从具有多个字符和数字列的数据集开始:
library(data.table)
my_table <- data.table(
name1 = letters[1:4],
name2 = LETTERS[23:26],
date = as.POSIXct(c("2018-04-04", "2018-04-04", "2018-04-05", "2018-04-06")),
value1 = c(1, 2, 8, 3),
value2 = c(9, 4, 2, 5)
)
my_table
# name1 name2 date value1 value2
# 1: a W 2018-04-04 1 9
# 2: b X 2018-04-04 2 4
# 3: c Y 2018-04-05 8 2
# 4: d Z 2018-04-06 3 5
我们可以使用Filter
函数创建仅包含数字列的新数据集,然后获取这些列的名称。之后,我们将对字符列执行相同的操作。
numeric_data <- Filter(is.numeric, my_table)
numeric_columns <- names(numeric_data)
numeric_columns
# [1] "value1" "value2"
character_data <- Filter(is.character, my_table)
character_columns <- names(character_data)
character_columns
# [1] "name1" "name2"
如果您担心大数据效率低下,请不要这样做。这里没有任何数据实际被复制。
address(my_table$name1)
# [1] "0000000004601058"
address(character_data$name1)
# [1] "0000000004601058"
然后,我们会按date
列的值汇总字符和数值。 j
的{{1}}部分可以包含任何常规R代码,这些代码在每个副组内执行。 data.table
变量是按组的子集.SD
,因此我们可以使用它来抓取数字或字符列。
data.table