我有一个名为“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
我想删除第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
关键思想是,你把想要删除的行组成一个集合,并保留这个集合的补项。
在R中,集合的补由'-'操作符给出。
因此,假设data.frame被称为myData:
data.frame
myData
myData[-c(2, 4, 6), ] # notice the -
当然,如果你想完全删除这些行,不要忘记“重新分配”myData——否则,R只打印结果。
myData <- myData[-c(2, 4, 6), ]
你也可以使用所谓的布尔向量,也就是logical:
logical
row_to_keep = c(TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE) myData = myData[row_to_keep,]
注意,!操作符充当了一个NOT,即!TRUE == FALSE:
!
!TRUE == FALSE
myData = myData[!row_to_keep,]
与@mrwab的答案相比,这似乎有点麻烦(+1 btw:)),但逻辑向量可以动态生成,例如,当列值超过某个值时:
myData = myData[myData$A > 4,] myData = myData[!myData$A > 4,] # equal to myData[myData$A <= 4,]
你可以把一个布尔向量转换成一个索引向量:
row_to_keep = which(myData$A > 4)
最后,一个非常巧妙的技巧是,你不仅可以将这种子集用于提取,还可以用于赋值:
myData$A[myData$A > 4,] <- NA
其中列A被分配为NA(不是一个数字),其中A超过4。
A
NA
对于快速和肮脏的分析,您可以根据顶部的答案通过数字删除data.frame的行。也就是说,
newdata <- myData[-c(2, 4, 6), ]
但是,如果试图编写健壮的数据分析脚本,通常应该避免按数字位置删除行。这是因为数据中的行顺序将来可能会改变。data.frame或数据库表的一般原则是行顺序不重要。如果顺序很重要,则应该将其编码在data.frame中的一个实际变量中。
例如,假设您导入了一个数据集,并在检查了数据并确定了要删除的行的行号之后,按数字位置删除了行。但是,在稍后的某个时刻,您将进入原始数据并查看并重新排序数据。您的行删除代码现在将删除错误的行,更糟糕的是,您不太可能得到任何警告您已经发生这种情况的错误。
更好的策略是根据行的实质性和稳定属性删除行。例如,如果你有一个id列变量唯一地标识每个情况,你可以使用它。
id
newdata <- myData[ !(myData$id %in% c(2,4,6)), ]
其他时候,您将有一个可以指定的正式排除标准,并且您可以使用R中的许多子集工具之一来基于该规则排除情况。
在数据帧中创建id列或使用任何列名来标识行。使用索引删除是不公平的。
使用subset函数创建新帧。
subset
updated_myData <- subset(myData, id!= 6) print (updated_myData) updated_myData <- subset(myData, id %in% c(1, 3, 5, 7)) print (updated_myData)
简化顺序:
mydata[-(1:3 * 2), ]
顺序如下:
mydata[seq(1, nrow(mydata), by = 2) , ]
由负序排列:
mydata[-seq(2, nrow(mydata), by = 2) , ]
或者如果你想通过选择奇数来子集:
mydata[which(1:nrow(mydata) %% 2 == 1) , ]
或者如果你想通过选择奇数来子集,版本2:
mydata[which(1:nrow(mydata) %% 2 != 0) , ]
或者如果你想通过过滤偶数来子集:
mydata[!which(1:nrow(mydata) %% 2 == 0) , ]
或者如果你想通过过滤偶数来子集,版本2:
mydata[!which(1:nrow(mydata) %% 2 != 1) , ]
从员工中删除Dan。data -不需要管理新的data.frame。
employee.data <- subset(employee.data, name!="Dan")
下面是一个按索引删除一行的快速而简单的函数。
removeRowByIndex <- function(x, row_index) { nr <- nrow(x) if (nr < row_index) { print('row_index exceeds number of rows') } else if (row_index == 1) { return(x[2:nr, ]) } else if (row_index == nr) { return(x[1:(nr - 1), ]) } else { return (x[c(1:(row_index - 1), (row_index + 1):nr), ]) } }
它的主要缺陷是row_index参数没有遵循作为值向量的R模式。可能还有其他问题,因为我只花了几分钟编写和测试它,而且在过去几周才开始使用R。任何评论和改进这将是非常欢迎的!
为了完整起见,我将添加这可以用dplyr完成,也可以用slice完成。使用它的好处是它可以成为管道工作流的一部分。
dplyr
slice
df <- df %>% . . slice(-c(2, 4, 6)) %>% . .
当然,您也可以在没有管道的情况下使用。
df <- slice(df, -c(2, 4, 6))
“非向量”格式,-c(2, 4, 6)表示获取第2行、第4行和第6行中不的所有内容。对于一个使用范围的例子,假设你想删除前5行,你可以使用slice(df, 6:n())。有关更多示例,请参见文档。
-c(2, 4, 6)
slice(df, 6:n())
用名字来识别:
代码:
Rows<-which(grepl("unique ID", DF$Column)) DF2<-DF[-c(Rows),] DF2
Chem.Report<-subset(Chem.Report, Chem_ID!="Standard")
Chem_ID是列名。 !对于排除