R 使用NAs时跨多个列的最小值和最大值

R 使用NAs时跨多个列的最小值和最大值,r,max,min,na,inf,R,Max,Min,Na,Inf,对于以下样本数据dat,在处理NAs时,是否有方法计算min和max。我的意见是: dat <- read.table(text = "ID Name PM TP2 Sigma 1 Tim 1 2 3 2 Sam 0 NA 1 3 Pam 2

对于以下样本数据
dat
,在处理
NA
s时,是否有方法计算
min
max
。我的意见是:

dat <- read.table(text = "ID  Name   PM      TP2   Sigma
                          1   Tim    1       2    3
                          2   Sam    0       NA   1
                          3   Pam    2       1    NA
                          4   Ali    1       0    2
                          NA  NA     NA      NA   NA
                          6   Tim    2       0    7", header = TRUE)
我的努力

1-我看到过类似的帖子,但没有一篇帖子讨论过一列中所有条目都是
NA
s的问题,例如。, 基于此,我尝试了
pmin()
pmax()
,但它们对我不起作用

2-另一个类似的问题是。同样,不需要处理
NA
s

3-最后,这个问题讨论的是
NA
,但并非列中的所有元素都缺少值

4-此外,一些解决方案要求手动键入要包含的列列表,我的原始数据非常广泛,我希望有一个更简单的解决方案,可以用数字而不是名称来表示列

部分解决方案

我尝试了以下解决方案,但
Min
列的结果是
Inf
,而
Max
列的结果是
-Inf

dat$min = apply(dat[,c(2:4)], 1, min, na.rm = TRUE)
dat$max = apply(dat[,c(2:4)], 1, max, na.rm = TRUE)
我可以使用以下方法手动清除
Inf

dat$min[is.infinite(dat$min)] = NA

但我想知道是否有更好的方法来实现我想要的结果?如有任何建议,将不胜感激


谢谢您的时间。

以下解决方案似乎与
transform()
函数配合使用:

dat <- transform(dat, min = pmin(PM, TP2, Sigma))
dat <- transform(dat, max = pmin(PM, TP2, Sigma))

我正在发布我能想到的唯一解决方案,以防其他人偶然发现类似问题。

以下解决方案似乎与
transform()
函数配合使用:

dat <- transform(dat, min = pmin(PM, TP2, Sigma))
dat <- transform(dat, max = pmin(PM, TP2, Sigma))

我正在发布我能想到的唯一解决方案,以防其他人遇到类似问题。

如果所有值都是
NA
,则可以使用
hablar
min\uucode>和
max\ucode>函数返回
NA

library(dplyr)
library(hablar)

dat %>%
  rowwise() %>%
  mutate(min = min_(c_across(-ID)), 
         max = max_(c_across(-ID)))
您也可以将其与
apply
-

cbind(dat, t(apply(dat[-1], 1, function(x) c(min = min_(x), max = max_(x)))))

#  ID PM TP2 Sigma min max
#1  1  1   2     3   1   3
#2  2  0  NA     1   0   1
#3  3  2   1    NA   1   2
#4  4  1   0     2   0   2
#5 NA NA  NA    NA  NA  NA
#6  5  2   0     7   0   7

如果所有值都是
NA
,则可以使用
hablar
min\u
max\u
函数返回
NA

library(dplyr)
library(hablar)

dat %>%
  rowwise() %>%
  mutate(min = min_(c_across(-ID)), 
         max = max_(c_across(-ID)))
您也可以将其与
apply
-

cbind(dat, t(apply(dat[-1], 1, function(x) c(min = min_(x), max = max_(x)))))

#  ID PM TP2 Sigma min max
#1  1  1   2     3   1   3
#2  2  0  NA     1   0   1
#3  3  2   1    NA   1   2
#4  4  1   0     2   0   2
#5 NA NA  NA    NA  NA  NA
#6  5  2   0     7   0   7

方法可能是将
pmin
pmax
do一起使用。调用

dat$min <- do.call(pmin, c(dat[,c(3:5)], na.rm=TRUE))
dat$max <- do.call(pmax, c(dat[,c(3:5)], na.rm=TRUE))
dat
#  ID Name PM TP2 Sigma min max
#1  1  Tim  1   2     3   1   3
#2  2  Sam  0  NA     1   0   1
#3  3  Pam  2   1    NA   1   2
#4  4  Ali  1   0     2   0   2
#5 NA <NA> NA  NA    NA  NA  NA
#6  6  Tim  2   0     7   0   7

dat$min方法可能是将
pmin
pmax
do一起使用。调用

dat$min <- do.call(pmin, c(dat[,c(3:5)], na.rm=TRUE))
dat$max <- do.call(pmax, c(dat[,c(3:5)], na.rm=TRUE))
dat
#  ID Name PM TP2 Sigma min max
#1  1  Tim  1   2     3   1   3
#2  2  Sam  0  NA     1   0   1
#3  3  Pam  2   1    NA   1   2
#4  4  Ali  1   0     2   0   2
#5 NA <NA> NA  NA    NA  NA  NA
#6  6  Tim  2   0     7   0   7

dat$min我将使用data.table执行此任务。我使用行和来计算na行的数量,并将其与总列数进行比较。我只在dat.new中使用至少有一个nonNA值的所有列。然后可以像通常一样使用na.rm=T

我希望这个小代码能帮助你


library(data.table)

#your data
dat <- read.table(text = "ID    PM      TP2   Sigma
                          1      1       2    3
                  2      0       NA   1
                  3      2       1    NA
                  4      1       0    2
                  NA     NA      NA   NA
                  5      2       0    7", header = TRUE)

#generate data.table and add id
dat <- data.table(dat)
number.cols <- dim(dat)[2] #4
dat[,id:=c(1:dim(dat)[1])]
# > dat
#     ID PM TP2 Sigma id
# 1:  1  1   2     3  1
# 2:  2  0  NA     1  2
# 3:  3  2   1    NA  3
# 4:  4  1   0     2  4
# 5: NA NA  NA    NA  5
# 6:  5  2   0     7  6

#use new data.table to select all rows with at least one nonNA value
dat.new <- dat[rowSums(is.na(dat))<number.cols,]
dat.new[, MINv:=min(.SD, na.rm=T), by=id]
dat.new[, MAXv:=max(.SD, na.rm=T), by=id]

#if you need it merged to the old data
dat <- merge(dat, dat.new[,.(id,MINv,MAXv)], by="id")

库(数据表)
#你的数据

dat我将使用data.table执行此任务。我使用行和来计算na行的数量,并将其与总列数进行比较。我只在dat.new中使用至少有一个nonNA值的所有列。然后可以像通常一样使用na.rm=T

我希望这个小代码能帮助你


library(data.table)

#your data
dat <- read.table(text = "ID    PM      TP2   Sigma
                          1      1       2    3
                  2      0       NA   1
                  3      2       1    NA
                  4      1       0    2
                  NA     NA      NA   NA
                  5      2       0    7", header = TRUE)

#generate data.table and add id
dat <- data.table(dat)
number.cols <- dim(dat)[2] #4
dat[,id:=c(1:dim(dat)[1])]
# > dat
#     ID PM TP2 Sigma id
# 1:  1  1   2     3  1
# 2:  2  0  NA     1  2
# 3:  3  2   1    NA  3
# 4:  4  1   0     2  4
# 5: NA NA  NA    NA  5
# 6:  5  2   0     7  6

#use new data.table to select all rows with at least one nonNA value
dat.new <- dat[rowSums(is.na(dat))<number.cols,]
dat.new[, MINv:=min(.SD, na.rm=T), by=id]
dat.new[, MAXv:=max(.SD, na.rm=T), by=id]

#if you need it merged to the old data
dat <- merge(dat, dat.new[,.(id,MINv,MAXv)], by="id")

库(数据表)
#你的数据

dat Thank@Ronak Shah,第一种解决方案是否也要求我明确排除决策中不应考虑的所有列?像上面的
ID
列吗?你能解释一下,c_Cross是什么意思吗?是的,我用了
c_Cross(-ID)
ID
排除在决策之外
c_Cross
rowwise
一起用于将多个列组合在一起。有没有更快的方法,可以不用写列名,而是指定列号以进行排除和决策?是的,
c_Cross(-1)
可以工作,所以
c_Cross(2:4)
谢谢@Ronak Shah,第一种解决方案是否也要求我明确排除决策过程中不应考虑的所有列?像上面的
ID
列吗?你能解释一下,c_Cross是什么意思吗?是的,我用了
c_Cross(-ID)
ID
排除在决策之外
c_Cross
rowwise
一起用于将多个列组合在一起。有没有更快的方法,可以不写列名,而是指定列号以进行排除和决策?是的,
c_Cross(-1)
可以工作,所以
c_Cross(2:4)
谢谢,这在我的情况下也可以工作。谢谢,这在我的情况下也适用。