![](/img/trans.png)
[英]In R, how do I delete rows in a data frame by column names of another data frame?
[英]How do I delete rows in a data frame?
我有一个名为“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
:
myData[-c(2, 4, 6), ] # notice the -
当然,如果您想完全删除这些行,请不要忘记“重新分配” myData
---否则,R 只会打印结果。
myData <- myData[-c(2, 4, 6), ]
您还可以使用所谓的布尔向量,也就是logical
向量:
row_to_keep = c(TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE)
myData = myData[row_to_keep,]
请注意!
运算符充当 NOT,即!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。
对于快速和脏分析,您可以根据最佳答案按编号删除 data.frame 的行。 IE,
newdata <- myData[-c(2, 4, 6), ]
但是,如果您正在尝试编写健壮的数据分析脚本,则通常应避免按数字位置删除行。 这是因为数据中行的顺序将来可能会发生变化。 data.frame 或数据库表的一般原则是行的顺序无关紧要。 如果顺序确实重要,则应将其编码在 data.frame 中的实际变量中。
例如,假设您在检查数据并确定要删除的行的行号后,导入了一个数据集并按数字位置删除了行。 但是,在稍后的某个时间点,您进入原始数据并环顾四周并重新排序数据。 您的行删除代码现在将删除错误的行,更糟糕的是,您不太可能收到警告您发生这种情况的任何错误。
更好的策略是根据行的实质性和稳定属性删除行。 例如,如果您有一个唯一标识每个案例的id
列变量,您可以使用它。
newdata <- myData[ !(myData$id %in% c(2,4,6)), ]
其他时候,您将拥有可以指定的正式排除标准,并且您可以使用 R 中的众多子集工具之一来排除基于该规则的案例。
在您的数据框中创建 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)
按简化顺序:
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) , ]
从employee.data 中删除Dan - 无需管理新的data.frame。
employee.data <- subset(employee.data, name!="Dan")
为了完整dplyr
,我将补充说,这也可以使用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())
。 有关更多示例,请参阅文档。
这是一个快速而肮脏的函数,用于按索引删除一行。
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。 非常欢迎对此提出任何意见和改进!
通过名称识别:
代码:
Rows<-which(grepl("unique ID", DF$Column))
DF2<-DF[-c(Rows),]
DF2
使用唯一 ID 时的另一种方法是对数据进行子集化:*这来自我想删除化学标准的实际报告
Chem.Report<-subset(Chem.Report, Chem_ID!="Standard")
Chem_ID 是列名。 这 ! 对排除很重要
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.