我有一个
data
,如下:
data<-data.frame(id=c(1,2,3,4,5,6,7,8,9,10),
Wt=c(91,92,85,205,285,43,95,75,76,NA),
Ht=c(185,182,173,171,600,650,NA,890,NA,NA))
Wt
代表体重(公斤),Ht
代表身高(厘米)。在此示例中,我想将大于 200 的 Wt
值视为异常值,并更改为一些特定数字。
另外,我想将大于 250 的 Ht
值视为异常值并更改为 NA
。
在我的实际data
中,Wt
中的异常值很少,而Ht
中的异常值很多。
因此,我可以使用下面的代码找到 Wt
的异常值:
a1<-data$Wt
a1<-data.frame(a1)
a1<-na.omit(a1)
b1<-a1[a1$a1>200, ]
b1 #205,285
我想把205改成80,把285改成90。(因为,在我的实际数据中,
Wt
的异常值很少,这样我就可以单独更改它们。)
另外,我想让 Ht
的值大于 250 作为 NA
。所以我的预期输出如下:
data<-data.frame(id=c(1,2,3,4,5,6,7,8,9,10),
Wt=c(91,92,85,80,90,43,95,75,76,NA),
Ht=c(185,182,173,171,NA,NA,NA,NA,NA,NA))
通过参考使用data.table
进行操作:
library(data.table)
setDT(data)
data[Ht > 250, Ht := NA]
data[Wt == 205, Wt := 80]
data[Wt == 285, Wt := 90]
data
id Wt Ht
1: 1 91 185
2: 2 92 182
3: 3 85 173
4: 4 80 171
5: 5 90 NA
6: 6 43 NA
7: 7 95 NA
8: 8 75 NA
9: 9 76 NA
10: 10 NA NA
欲了解更多信息,请参阅:简介。
ifelse
中建议的
data.table
方法,您可以执行以下操作。这个还是参考更新,所以还是没必要写
data <- data %>% ...
之类的。
library(data.table)
setDT(data)
data[, `:=`(Ht = fifelse(Ht > 250, NA_real_, Ht),
Wt = fcase(Wt == 205, 80,
Wt == 285, 90,
rep(TRUE, .N), Wt))]
请注意,fifelse
是
data.table
的fast
ifelse
,我使用
fcase
来一起处理两个
Wt
条件(尽管
rep(TRUE, .N)
技巧有点hacky,所以也许最好只使用两个
fifelse
调用
Wt
而不是
fcase
)。
plyr::mapvalues
。即使
plyr
已经退役,你也可以使用
body(plyr::mapvalues)
并做同样的事情,因为它的依赖很少,因此将代码放入你自己的项目中。
ifelse
和
tidyverse
的功能插入任何您想要的值。作为示例,我在这里使用
mutate
创建变量,并使用
ifelse
来简单地转换您想要的值。下面基本上只是您的数据和两个函数组合成一个命令:
library(tidyverse)
data %>%
mutate(Wt = ifelse(Wt > 200,
"9999",
Wt),
Ht = ifelse(Ht > 250,
"NA",
Ht))
下面注释的是我对代码所做的事情:
library(tidyverse) # load this library for %>% and mutate
data %>% # use this data
mutate(Wt = ifelse(Wt > 200, # take Wt over 200
"9999", # replace with this value
Wt), # otherwise use the original Wt value
Ht = ifelse(Ht > 250, # take Ht over 250
"NA", # replace with this value
Ht)) # otherwise use the original Ht value
根据您的使用方式,它应该为您提供任何所需的输出:
id Wt Ht
1 1 91 185
2 2 92 182
3 3 85 173
4 4 9999 171
5 5 9999 NA
6 6 43 NA
7 7 95 <NA>
8 8 75 NA
9 9 76 <NA>
10 10 <NA> <NA>
尝试一下,让我知道你的想法!