如何删除数据框中的行?

R n*_*bie 203 row r

我有一个名为"mydata"的数据框,如下所示:

   A  B  C   D 
1. 5  4  4   4 
2. 5  4  4   4 
3. 5  4  4   4 
4. 5  4  4   4 
5. 5  4  4   4 
6. 5  4  4   4 
7. 5  4  4   4 
Run Code Online (Sandbox Code Playgroud)

我想删除第2,4,6行.例如,像这样:

   A  B  C   D
1. 5  4  4  4 
3. 5  4  4  4 
5. 5  4  4  4 
7. 5  4  4  4 
Run Code Online (Sandbox Code Playgroud)

A5C*_*2T1 308

关键的想法是,您要形成一组要删除的行,并保留该集的补充.

在R中,集合的补集由' - '运算符给出.

所以,假设data.frame被称为myData:

myData[-c(2, 4, 6), ]   # notice the -
Run Code Online (Sandbox Code Playgroud)

当然,myData如果你想完全放弃那些行,不要忘记"重新分配" - 否则,R只打印结果.

myData <- myData[-c(2, 4, 6), ]
Run Code Online (Sandbox Code Playgroud)

  • 不要忘记在那里注意`,`!;) (55认同)
  • @road_to_quantdom,在那里添加一个`drop = FALSE`. (4认同)
  • "在R中,集合的补集由' - '运算符给出" - >这是一个非常误导性的措辞.消极指数被删除,就是这样,没有补充的概念.如果你使用逻辑并尝试使用`-`它将无法工作,因为逻辑的补码运算符是`!`.行中c(2,4,6)的补码宁可是setdiff(c(2,4,6),1:nrow(myData)),也不是c(-2,-4,-6)虽然与`[`一起使用时两者都会产生相同的行. (3认同)
  • @Speldosa,`myData[-c(2, 4, 6),,drop=F]`。实际上,我建议您始终在任何矩阵访问中的 `]` 之前插入 `,drop=F`。 (3认同)
  • 如果您的数据框只有一列,该怎么办?它似乎放弃了整个结构并输出了值的向量 (2认同)
  • 请查看 https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=17282,当要删除的集合为空时,它会处理特殊的极端情况。 (2认同)

Pau*_*tra 76

您还可以使用所谓的布尔向量,也就是logical:

row_to_keep = c(TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE)
myData = myData[row_to_keep,]
Run Code Online (Sandbox Code Playgroud)

请注意,!运算符充当NOT,即!TRUE == FALSE:

myData = myData[!row_to_keep,]
Run Code Online (Sandbox Code Playgroud)

与@mrwab的答案(+1 btw :)相比,这看起来有点麻烦,但是可以动态生成逻辑向量,例如,当列值超过某个值时:

myData = myData[myData$A > 4,]
myData = myData[!myData$A > 4,] # equal to myData[myData$A <= 4,]
Run Code Online (Sandbox Code Playgroud)

您可以将布尔向量转换为索引向量:

row_to_keep = which(myData$A > 4)
Run Code Online (Sandbox Code Playgroud)

最后,一个非常巧妙的技巧是你可以使用这种子集不仅用于提取,还用于赋值:

myData$A[myData$A > 4,] <- NA
Run Code Online (Sandbox Code Playgroud)

其中列A的分配NA(不是数字)A超过4.


Jer*_*lim 55

按行号删除的问题

对于快速和脏分析,您可以按照最佳答案按编号删除data.frame的行.也就是说,

newdata <- myData[-c(2, 4, 6), ] 
Run Code Online (Sandbox Code Playgroud)

但是,如果您尝试编写健壮的数据分析脚本,通常应避免按数字位置删除行.这是因为数据中行的顺序将来可能会发生变化.data.frame或数据库表的一般原则是行的顺序无关紧要.如果顺序很重要,则应将其编码为data.frame中的实际变量.

例如,假设您在检查数据并识别要删除的行的行号后导入数据集并按数字位置删除行.但是,在稍后的某个时刻,您将进入原始数据并浏览并重新排序数据.您的行删除代码现在将删除错误的行,更糟糕的是,您不太可能收到任何错误警告您已发生这种情况.

更好的战略

更好的策略是根据行的实质和稳定属性删除行.例如,如果您有一个id唯一标识每个案例的列变量,则可以使用它.

newdata <- myData[ !(myData$id %in% c(2,4,6)), ]
Run Code Online (Sandbox Code Playgroud)

其他时候,您将有一个可以指定的正式排除标准,您可以使用R中的许多子集工具之一来排除基于该规则的案例.


小智 10

在数据框中创建id列,或使用任何列名来标识行.使用索引是不公平的删除.

使用subset函数创建新框架.

updated_myData <- subset(myData, id!= 6)
print (updated_myData)

updated_myData <- subset(myData, id %in% c(1, 3, 5, 7))
print (updated_myData)
Run Code Online (Sandbox Code Playgroud)


Elí*_*osa 7

按简化顺序:

mydata[-(1:3 * 2), ]
Run Code Online (Sandbox Code Playgroud)

按顺序:

mydata[seq(1, nrow(mydata), by = 2) , ]
Run Code Online (Sandbox Code Playgroud)

按负序:

mydata[-seq(2, nrow(mydata), by = 2) , ]
Run Code Online (Sandbox Code Playgroud)

或者,如果您想通过选择奇数来进行子集化:

mydata[which(1:nrow(mydata) %% 2 == 1) , ]
Run Code Online (Sandbox Code Playgroud)

或者,如果您想通过选择奇数来进行子集,则版本2:

mydata[which(1:nrow(mydata) %% 2 != 0) , ]
Run Code Online (Sandbox Code Playgroud)

或者,如果您想通过过滤偶数数字来进行子集化:

mydata[!which(1:nrow(mydata) %% 2 == 0) , ]
Run Code Online (Sandbox Code Playgroud)

或者,如果您希望通过过滤偶数数字来进行子集化,则版本2:

mydata[!which(1:nrow(mydata) %% 2 != 1) , ]
Run Code Online (Sandbox Code Playgroud)


小智 6

从employee.data 中删除Dan - 无需管理新的data.frame。

employee.data <- subset(employee.data, name!="Dan")
Run Code Online (Sandbox Code Playgroud)


Rya*_* H. 5

为了完整起见,我将补充说,这也可以dplyr使用slice. 使用它的优点是它可以成为管道工作流的一部分。

df <- df %>%
  .
  .
  slice(-c(2, 4, 6)) %>%
  .
  .
Run Code Online (Sandbox Code Playgroud)

当然,你也可以不用管道来使用它。

df <- slice(df, -c(2, 4, 6))
Run Code Online (Sandbox Code Playgroud)

“非向量”格式-c(2, 4, 6)意味着获取不在第2、4 和 6 行的所有内容。例如,使用范围的示例,假设您想删除前 5 行,您可以执行slice(df, 6:n()). 有关更多示例,请参阅文档