如何在R中按条件删除行?

mefy6pfw  于 2023-01-22  发布在  其他
关注(0)|答案(1)|浏览(271)

我是R的新手,我想知道R中是否有一个相反的代码?
例如,当我运行下面的代码时,它会保留10到50之间的所有数据,并删除其他所有数据。下面的代码对我很有效,没有问题。

data <- data[which(data$age>10 & data$age<50),]

但是我想知道是否有一个代码可以做相反的事情?意思是--〉我想从数据中删除特定的行,所以与其有一个代码说要保留什么,我想有一个代码,指示要删除什么,如果这有意义的话?我想按条件删除特定的行。
我试过使用子集代码,但是我不能让它工作。下面的代码是我试过但没有工作的代码

data2 <- subset(data1, data1$gender=='male')

性别是一个列,有男性和女性,我需要一个代码,只删除男性。

rta7y2nd

rta7y2nd1#

虽然这应该是一个评论,因为你说你是新的R让我花更多的空间来解释这在一个非技术性的方式,因为它是明确的有一些混乱。
首先,当你在R中使用方括号(即df[x,y])进行索引时,x部分(逗号之前)查看行,而y部分查看列。你的问题标题问的是删除列,但你的问题问的是删除行。所以我将介绍这两个部分。
假设您有这些数据(注意有些数据缺少(NA)值):

set.seed(123)
n <- 10
df <- data.frame(Age = sample(c(1:100, NA), n, replace = TRUE),
                 Gender = sample(c("Male", "Female", NA), n, replace = TRUE),
                 Cofactor = rep(LETTERS, length.out = n),
                 Cofactor2 = sample(c("Yes", "No", "Maybe", NA), n, replace = TRUE),
                 Cofactor3 = runif(n))

#    Age Gender Cofactor Cofactor2  Cofactor3
# 1   31 Female        A       Yes 0.02461368
# 2   79   Male        B     Maybe 0.47779597
# 3   51 Female        C      <NA> 0.75845954
# 4   14   <NA>        D        No 0.21640794
# 5   67   Male        E     Maybe 0.31818101
# 6   42   <NA>        F        No 0.23162579
# 7   50   <NA>        G       Yes 0.14280002
# 8   43   Male        H        No 0.41454634
# 9   NA   Male        I     Maybe 0.41372433
# 10  14   Male        J      <NA> 0.36884545

删除

您可以使用数字按行位置索引行-即,如果您要保留或删除前三行:

# keep 
df[1:3, ]

# drop
df[-c(1:3),]

请注意,命令位于x索引位置(逗号左侧)。如果要删除男性的观测(行),可以通过以下几种方式执行此操作。例如:

df[!(df$Gender %in% "Male"),]

# or using `which()`
df[-(which(df$Gender %in% "Male")),]

#   Age Gender Cofactor1  Cofactor2
# 1  31 Female       Yes 0.02461368
# 3  51 Female      <NA> 0.75845954
# 4  14   <NA>        No 0.21640794
# 6  42   <NA>        No 0.23162579
# 7  50   <NA>       Yes 0.14280002

!的意思是“非”--所以这是“选择 * 非 * 男性的行”-- * 包括 * NA值。
如果您这样做:

df[df$Gender %in% "Female",]

# or 
df[which(df$Gender %in% "Female"),]

#   Age Gender Cofactor1  Cofactor2
# 1  31 Female       Yes 0.02461368
# 3  51 Female      <NA> 0.75845954

这将是“包括所有性别为女性的人”-注意NA!=女性,所以他们不包括在内。
类似地,如果要在Cofactor1中同时包含“yes”和“maybe”:

df[df$Cofactor1 %in% c("Yes", "Maybe"),]

#   Age Gender Cofactor1  Cofactor2
# 1  31 Female       Yes 0.02461368
# 2  79   Male     Maybe 0.47779597
# 5  67   Male     Maybe 0.31818101
# 7  50   <NA>       Yes 0.14280002
# 9  NA   Male     Maybe 0.41372433

请注意,我使用的是%in%,而不是==,这是因为vector recycling-看看当我使用==时会发生什么(提示,它会产生不想要的结果):

df[df$Cofactor1 == c("Yes", "Maybe"),]

#     Age Gender Cofactor1  Cofactor2
#1     31 Female       Yes 0.02461368
#2     79   Male     Maybe 0.47779597
#NA    NA   <NA>      <NA>         NA
#7     50   <NA>       Yes 0.14280002
#NA.1  NA   <NA>      <NA>         NA

使用==的正确方法要冗长得多(df[(df$Cofactor1 == "Yes"| df$Cofactor1 == "Maybe") & !is.na(df$Cofactor1),],所以在这里使用%in%是一个很好的选择。

保留/删除

索引列位于索引的y位置(逗号的右侧)。如果数据中有大量不需要的列,只需通过按名称(或列号:

df[,c("Age", "Gender")]

# or df[, 1:2]

#    Age Gender
# 1   31 Female
# 2   79   Male
# 3   51 Female
# 4   14   <NA>
# 5   67   Male
# 6   42   <NA>
# 7   50   <NA>
# 8   43   Male
# 9   NA   Male
# 10  14   Male

但是您只能按编号删除列(我知道,这有点奇怪)-所以您不能df[,-c("Age", "Gender")]删除列,但是可以按df[,-c(1:2)]删除列
在我的工作中,首选的是按名称删除,因为列会有一些移位--这样我就可以准确地知道要删除的是什么。我使用的一个解决方案是将grepnames(df)一起使用,以确定要删除的列的位置。
这是一个小技巧,所以要小心。如果我想删除名称中以“Cofactor”开头的 * 所有 * 列:

dropcols <- grep("Cofactor", names(df))

# or to ignore case
# grep("Cofactor", names(df), ignore.case = TRUE)
# [1] 3 4 5

如果我想删除Cofactor,但保留Cofactor1Cofactor2,我可以使用\\b在上面放置一个word boundary

dropcols <- grep("\\bCofactor\\b", names(df))
[1] 3

因此,要删除列,您可以像这样简单地建立索引:

dropcols <- grep("Cofactor", names(df))
df[, -dropcols]

#    Age Gender
# 1   31 Female
# 2   79   Male
# 3   51 Female
# 4   14   <NA>
# 5   67   Male
# 6   42   <NA>
# 7   50   <NA>
# 8   43   Male
# 9   NA   Male
# 10  14   Male

相关问题