R获取数据框中的最小值,选择2列上的行
我有一个数据帧,就像我在下面简化的那个。我想首先根据列X选择具有相同值的行,然后在该选择中根据列Y选择具有相同值的行。然后从该选择中,我想取最小值。我现在正在使用forloop,但似乎有一种更简单的方法。谢谢R获取数据框中的最小值,选择2列上的行,r,dataframe,select,multiple-columns,min,R,Dataframe,Select,Multiple Columns,Min,我有一个数据帧,就像我在下面简化的那个。我想首先根据列X选择具有相同值的行,然后在该选择中根据列Y选择具有相同值的行。然后从该选择中,我想取最小值。我现在正在使用forloop,但似乎有一种更简单的方法。谢谢 set.seed(123) data<-data.frame(X=rep(letters[1:3], each=8),Y=rep(c(1,2)),Z=sample(1:100, 12)) data X Y Z 1 a 1 76 2 a 1 22 3 a 2 32
set.seed(123)
data<-data.frame(X=rep(letters[1:3], each=8),Y=rep(c(1,2)),Z=sample(1:100, 12))
data
X Y Z
1 a 1 76
2 a 1 22
3 a 2 32
4 a 2 23
5 b 1 14
6 b 1 40
7 b 2 39
8 b 2 35
9 c 1 15
10 c 1 13
11 c 2 21
12 c 2 42
以下是data.table解决方案:
library(data.table)
data = data.table(data)
data[, min(Z), by=c("X", "Y")]
根据OP的评论进行编辑:
如果我们排序所依据的其中一列中存在NA值,则会创建另一行:
data[2,2] <-NA
data[, min(Z,na.rm = T), by=c("X", "Y")]
X Y V1
1: a 1 31
2: a NA 79
3: a 2 14
4: b 1 31
5: b 2 14
6: c 1 50
7: c 2 25
我会成功的!现在的另一个答案是data.table,这是tidyverse。这两种方法都是处理数据清理和操作的非常有效的方法——熟悉其中一种可能会有所帮助 在base中,您可以使用aggregate从Z中获取最小值,并按剩余列分组,如:
aggregate(Z~.,data,min)
# X Y Z
#1 a 1 31
#2 b 1 31
#3 c 1 50
#4 a 2 14
#5 b 2 14
#6 c 2 25
如果组中存在NA:
data[2,2] <-NA
展示它:
aggregate(data$Z, list(X=data$X, Y=addNA(data$Y)), min)
# X Y x
#1 a 1 31
#2 b 1 31
#3 c 1 50
#4 a 2 14
#5 b 2 14
#6 c 2 25
#7 a <NA> 79
这段代码可以从将其拆分为多行中获益,但它可以工作。在Base-R中
do.call(rbind,
lapply(unlist(lapply(split(data,data$X), function(x) split(x,x$Y)),recursive=F), function(y) y[y$Z==min(y$Z),])
)
X Y Z
a.1 a 1 31
a.2 a 2 14
b.1 b 1 31
b.2 b 2 14
c.1 c 1 50
c.2 c 2 25
感谢将数据帧更改为数据表有什么不利之处吗?任何我应该考虑的事情…没有负面影响。data.table仍然是data.frame,这意味着它可以完成data.frame所能做的所有事情,只需增加一些功能。如果我错了,有人纠正我吗?NAs会被忽略吗?看起来是这样的:嗨,我用NA值编辑了答案。这就是你的意思吗?对不起,我指的是V1列中的NA值。它取最小值,忽略NA。但我认为最初的代码是正确的。做得好。
aggregate(Z~.,data,min)
# X Y Z
#1 a 1 31
#2 b 1 31
#3 c 1 50
#4 a 2 14
#5 b 2 14
#6 c 2 25
aggregate(data$Z, list(X=data$X, Y=addNA(data$Y)), min)
# X Y x
#1 a 1 31
#2 b 1 31
#3 c 1 50
#4 a 2 14
#5 b 2 14
#6 c 2 25
#7 a <NA> 79
do.call(rbind,
lapply(unlist(lapply(split(data,data$X), function(x) split(x,x$Y)),recursive=F), function(y) y[y$Z==min(y$Z),])
)
X Y Z
a.1 a 1 31
a.2 a 2 14
b.1 b 1 31
b.2 b 2 14
c.1 c 1 50
c.2 c 2 25