R中的数据表解决方案,用于查找组最小值/最大值
资料R中的数据表解决方案,用于查找组最小值/最大值,r,data.table,R,Data.table,资料 我有'student'和'score'列,希望使用data.table创建'min'和'max',简单地说就是忽略NA值的每个学生的最小值和最大值。如果所有值均为NA,则只需将“NA”列为最小值/最大值。您可以使用函数ave: data=data.frame("student"=c(1,1,1,2,2,2,3,3,3), "score"=c(NA,7,6,6,1,4,8,NA,3), "min"=c(6,6,6,1,1,1,3
我有'student'和'score'列,希望使用data.table创建'min'和'max',简单地说就是忽略NA值的每个学生的最小值和最大值。如果所有值均为NA,则只需将“NA”列为最小值/最大值。您可以使用函数
ave
:
data=data.frame("student"=c(1,1,1,2,2,2,3,3,3),
"score"=c(NA,7,6,6,1,4,8,NA,3),
"min"=c(6,6,6,1,1,1,3,3,3),
"max"=c(7,7,7,6,6,6,8,8,8))
结果:
data=data.frame("student"=c(1,1,1,2,2,2,3,3,3),
"score"=c(NA,7,6,6,1,4,8,NA,3))
data$min = ave(data$score, data$student, FUN = function(x){ min(x, na.rm = T) })
data$max = ave(data$score, data$student, FUN = function(x){ max(x, na.rm = T) })
函数
ave
将一个数值向量作为第一个参数,并且以下所有向量都是分组变量。FUN参数是您希望应用的函数。您可以使用函数ave
:
data=data.frame("student"=c(1,1,1,2,2,2,3,3,3),
"score"=c(NA,7,6,6,1,4,8,NA,3),
"min"=c(6,6,6,1,1,1,3,3,3),
"max"=c(7,7,7,6,6,6,8,8,8))
结果:
data=data.frame("student"=c(1,1,1,2,2,2,3,3,3),
"score"=c(NA,7,6,6,1,4,8,NA,3))
data$min = ave(data$score, data$student, FUN = function(x){ min(x, na.rm = T) })
data$max = ave(data$score, data$student, FUN = function(x){ max(x, na.rm = T) })
函数
ave
将一个数值向量作为第一个参数,并且以下所有向量都是分组变量。FUN参数是您希望应用的函数。使用数据。表
> data
student score min max
1 1 NA 6 7
2 1 7 6 7
3 1 6 6 7
4 2 6 1 6
5 2 1 1 6
6 2 4 1 6
7 3 8 3 8
8 3 NA 3 8
9 3 3 3 8
或使用dplyr
library(data.table)
setDT(data)
data[, c("min", "max"):= list(min(score, na.rm = TRUE),
max(score, na.rm = TRUE)), student]
data
# student score min max
#1: 1 NA 6 7
#2: 1 7 6 7
#3: 1 6 6 7
#4: 2 6 1 6
#5: 2 1 1 6
#6: 2 4 1 6
#7: 3 8 3 8
#8: 3 NA 3 8
#9: 3 3 3 8
使用
数据表
> data
student score min max
1 1 NA 6 7
2 1 7 6 7
3 1 6 6 7
4 2 6 1 6
5 2 1 1 6
6 2 4 1 6
7 3 8 3 8
8 3 NA 3 8
9 3 3 3 8
或使用dplyr
library(data.table)
setDT(data)
data[, c("min", "max"):= list(min(score, na.rm = TRUE),
max(score, na.rm = TRUE)), student]
data
# student score min max
#1: 1 NA 6 7
#2: 1 7 6 7
#3: 1 6 6 7
#4: 2 6 1 6
#5: 2 1 1 6
#6: 2 4 1 6
#7: 3 8 3 8
#8: 3 NA 3 8
#9: 3 3 3 8
但OP希望如果任何学生的所有分数都是NA,则返回NA。此解决方案修复了Inf问题
library(dplyr)
data %>%
group_by(student) %>%
mutate(min = min(score, na.rm = TRUE), max = max(score, na.rm = TRUE))
编辑:我不知道你为什么要这样做。将汇总统计数据与原始数据相结合是不好的做法。这会导致冗余/重复。当然,您只希望每个学生都有一个单独的结果:
min.na = function(x) if (all(is.na(x))) x[NA_integer_] else min(x, na.rm = TRUE)
max.na = function(x) if (all(is.na(x))) x[NA_integer_] else max(x, na.rm = TRUE)
dt[, c("min", "max") := list(min.na(score), max.na(score)), by=student]
dt
student score min max
1: 1 NA NA NA
2: 1 NA NA NA
3: 1 NA NA NA
4: 2 6 1 6
5: 2 1 1 6
6: 2 4 1 6
7: 3 8 3 8
8: 3 NA 3 8
9: 3 3 3 8
我知道最后一部分并不是他们要求的,但我总是检查他们要求的是他们真正想要的 但是OP想要返回NA,如果任何学生的所有分数都是NA。此解决方案修复了Inf问题
library(dplyr)
data %>%
group_by(student) %>%
mutate(min = min(score, na.rm = TRUE), max = max(score, na.rm = TRUE))
编辑:我不知道你为什么要这样做。将汇总统计数据与原始数据相结合是不好的做法。这会导致冗余/重复。当然,您只希望每个学生都有一个单独的结果:
min.na = function(x) if (all(is.na(x))) x[NA_integer_] else min(x, na.rm = TRUE)
max.na = function(x) if (all(is.na(x))) x[NA_integer_] else max(x, na.rm = TRUE)
dt[, c("min", "max") := list(min.na(score), max.na(score)), by=student]
dt
student score min max
1: 1 NA NA NA
2: 1 NA NA NA
3: 1 NA NA NA
4: 2 6 1 6
5: 2 1 1 6
6: 2 4 1 6
7: 3 8 3 8
8: 3 NA 3 8
9: 3 3 3 8
我知道最后一部分并不是他们要求的,但我总是检查他们要求的是他们真正想要的 另一个
数据表
选项:
dt[, .(min=min.na(score), max=max.na(score)), by=student]
student min max
1: 1 NA NA
2: 2 1 6
3: 3 3 8
另一个
数据表
选项:
dt[, .(min=min.na(score), max=max.na(score)), by=student]
student min max
1: 1 NA NA
2: 2 1 6
3: 3 3 8