替换data.frame列中的某些值

egdjgwm8  于 2023-07-31  发布在  其他
关注(0)|答案(2)|浏览(107)

我有一个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))

zbq4xfa0

zbq4xfa01#

  • 通过引用 * 使用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

字符串
有关详细信息,请参阅:Introduction to data.table的数据。
要在data.table中实现Shawn建议的ifelse方法,可以执行以下操作。这仍然是通过引用更新的,所以仍然不需要编写类似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))]


请注意,fifelsedata.tablefastifelse,我使用fcase一起处理两个Wt条件(尽管rep(TRUE, .N) trick有点笨拙,所以也许对Wt使用两个fifelse调用而不是fcase会更好)。
更新2023-07-17:如果你需要一个矢量化的选项,我建议你使用plyr::mapvalues。即使plyr已经退役,您也可以使用body(plyr::mapvalues)并将代码放入您自己的项目中。

ukxgm1gy

ukxgm1gy2#

上面的答案很有用。我还想添加一个替代答案,以防您发现它对学习其他函数有帮助。您可以使用ifelsetidyverse的功能插入任何想要的值。例如,我在这里使用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>


试试看,让我知道你的想法!

相关问题