如何检查行值是否与对应的列值匹配
How to check if row value matches corresponding column value
我有一个数据框,它是通过导入几个 .csv
文件然后将它们合并在一起创建的。
我读入的每个数据框都有第 8 行的列标题,前七行有一些描述性文本。
这就是出现重复行的原因 - 因为我无法使用第一个数据帧中第 8 行中的值,然后丢弃其余数据帧中的前 8 行(或者我可以 - 我'我确定这是可能的)。
最终,我想要发生的是:
- Read first .csv into data frame.
- Take values of row 8 to be column names
- Delete the first 8 rows.
- Read all other .csv files in, remove the first 8 rows from each one, and merge them all into the same data frame.
我现在面临一个问题,即某些行将包含与其对应的列名称相同的值。
例如,合并后的数据框现在看起来像这样:
--------------------------
| Name | Age | MonthBorn |
-------------------------
| Bob | 23 | September |
| Steve| 45 | June |
| Name | Age | MonthBorn | # Should be removed
| Sue | 74 | January |
| Name | Age | MonthBorn | # Should be removed
| Tracy| 31 | February |
--------------------------
问题是组合数据框几乎有 340,000 行深,所以我无法手动检查所有内容。另外,我大概知道每一行可能出现的位置,但我不能确定,因为可能会有变化。
我如何检查 row/cell 的值是否与相应的列名称匹配或设置导入过程如上文所述(项目符号)?
如果您的数据框大致如下所示:
Df <- Data.frame(Name, Age, MonthBorn)
然后您可以使用 ifelse 语句来测试 "MonthBorn" 是否连续出现。
Df$MonthBornTest <- ifelse(Df$MonthBorn == “MonthBorn”, “True”, “False”}
然后您应该能够执行此操作以删除包含 True 的行,从而有效地删除您不再需要的行。
Df <- Df[!(Df$MonthBornTest == “True”), ]
您的数据
df <- structure(list(Name_ = c("Bob", "Steve", "Bob", "Name", "Sue",
"Name", "Tracy"), `_Age_` = c("23", "45", "23", "Age", "74",
"Age", "31"), `_MonthBorn` = c("September", "June", "September",
"MonthBorn", "January", "MonthBorn", "February")), .Names = c("Name_",
"_Age_", "_MonthBorn"), row.names = c(NA, -7L), class = c("data.table",
"data.frame"))
解决方案
library(stringr)
df[!sapply(1:nrow(df), function(x) all(mapply(function(x,y) str_detect(x,y), colnames(df), df[x,]))),]
输出
Name_ _Age_ _MonthBorn
1: Bob 23 September
2: Steve 45 June
3: Bob 23 September
4: Sue 74 January
5: Tracy 31 February
我们可以使用 dplyr
和 tidyr
中的函数将所有列的内容组合在一起。之后,过滤掉与组合列名称相同的那些。 dt2
是最终输出。
# Create example data
dt <- read.table(text = "Name Age MonthBorn
Bob 23 September
Steve 45 June
Bob 23 September
Name Age MonthBorn
Sue 74 January
Name Age MonthBorn
Tracy 31 February",
header = TRUE, stringsAsFactors = FALSE)
# Load package
library(dplyr)
library(tidyr)
# Process the data
dt2 <- dt %>%
unite(ColName, everything(), sep = ", ", remove = FALSE) %>%
filter(ColName != toString(colnames(dt))) %>%
select(-ColName)
dt2
Name Age MonthBorn
1 Bob 23 September
2 Steve 45 June
3 Bob 23 September
4 Sue 74 January
5 Tracy 31 February
我有一个数据框,它是通过导入几个 .csv
文件然后将它们合并在一起创建的。
我读入的每个数据框都有第 8 行的列标题,前七行有一些描述性文本。
这就是出现重复行的原因 - 因为我无法使用第一个数据帧中第 8 行中的值,然后丢弃其余数据帧中的前 8 行(或者我可以 - 我'我确定这是可能的)。
最终,我想要发生的是:
- Read first .csv into data frame.
- Take values of row 8 to be column names
- Delete the first 8 rows.
- Read all other .csv files in, remove the first 8 rows from each one, and merge them all into the same data frame.
我现在面临一个问题,即某些行将包含与其对应的列名称相同的值。
例如,合并后的数据框现在看起来像这样:
--------------------------
| Name | Age | MonthBorn |
-------------------------
| Bob | 23 | September |
| Steve| 45 | June |
| Name | Age | MonthBorn | # Should be removed
| Sue | 74 | January |
| Name | Age | MonthBorn | # Should be removed
| Tracy| 31 | February |
--------------------------
问题是组合数据框几乎有 340,000 行深,所以我无法手动检查所有内容。另外,我大概知道每一行可能出现的位置,但我不能确定,因为可能会有变化。
我如何检查 row/cell 的值是否与相应的列名称匹配或设置导入过程如上文所述(项目符号)?
如果您的数据框大致如下所示:
Df <- Data.frame(Name, Age, MonthBorn)
然后您可以使用 ifelse 语句来测试 "MonthBorn" 是否连续出现。
Df$MonthBornTest <- ifelse(Df$MonthBorn == “MonthBorn”, “True”, “False”}
然后您应该能够执行此操作以删除包含 True 的行,从而有效地删除您不再需要的行。
Df <- Df[!(Df$MonthBornTest == “True”), ]
您的数据
df <- structure(list(Name_ = c("Bob", "Steve", "Bob", "Name", "Sue",
"Name", "Tracy"), `_Age_` = c("23", "45", "23", "Age", "74",
"Age", "31"), `_MonthBorn` = c("September", "June", "September",
"MonthBorn", "January", "MonthBorn", "February")), .Names = c("Name_",
"_Age_", "_MonthBorn"), row.names = c(NA, -7L), class = c("data.table",
"data.frame"))
解决方案
library(stringr)
df[!sapply(1:nrow(df), function(x) all(mapply(function(x,y) str_detect(x,y), colnames(df), df[x,]))),]
输出
Name_ _Age_ _MonthBorn
1: Bob 23 September
2: Steve 45 June
3: Bob 23 September
4: Sue 74 January
5: Tracy 31 February
我们可以使用 dplyr
和 tidyr
中的函数将所有列的内容组合在一起。之后,过滤掉与组合列名称相同的那些。 dt2
是最终输出。
# Create example data
dt <- read.table(text = "Name Age MonthBorn
Bob 23 September
Steve 45 June
Bob 23 September
Name Age MonthBorn
Sue 74 January
Name Age MonthBorn
Tracy 31 February",
header = TRUE, stringsAsFactors = FALSE)
# Load package
library(dplyr)
library(tidyr)
# Process the data
dt2 <- dt %>%
unite(ColName, everything(), sep = ", ", remove = FALSE) %>%
filter(ColName != toString(colnames(dt))) %>%
select(-ColName)
dt2
Name Age MonthBorn
1 Bob 23 September
2 Steve 45 June
3 Bob 23 September
4 Sue 74 January
5 Tracy 31 February