R - Creating/subset 循环或应用系列中的数据帧
R - Creating/subset dataframes within loop or apply family
如果多个变量(以相同后缀结尾)不包含 NA,我想对 R 数据帧进行子集化。
employee <- c('John Doe','Peter Gynn','Jolie Hope')
salary1 <- c(NA, 20400, 26800)
salary2 <- c(29045, NA, 78765)
date1 <- as.Date(c(NA,'2008-3-25','2007-3-14'))
date2 <- as.Date(c('2010-11-1',NA,'2007-3-14'))
employ.data <- data.frame(employee, salary1, salary2, date1, date2)
for (i in 1:2) {
assign("employ.data", i, subset(employ.data, !is.na(employ.data$date[i]) & !is.na(employ.data$salary[i])))
}
最终结果有望产生两个独立的数据帧,如下所示:
employ.data1:
| employee | salary1 | salary2 | date1 | date2 |
| Peter Gynn | 20400 | NA | 2008-03-25 | NA |
| Jolie Hope | 26800 | 78765 | 2007-03-14 | 2007-03-14 |
employ.data2:
| employee | salary1 | salary2 | date1 | date2 |
| John Doe | NA | 29045 | NA | 2010-11-01 |
| Jolie Hope | 26800 | 78765 | 2007-03-14 | 2007-03-14 |
提前致谢!
(预先:处理 list of frames 通常比使用 assign
动态创建对象更好。)
numfields <- grep("[0-9]+$", colnames(employ.data), value = TRUE)
split(numfields, gsub(".*?([0-9]+)$", "\1", numfields))
# $`1`
# [1] "salary1" "date1"
# $`2`
# [1] "salary2" "date2"
out <- lapply(split(numfields, gsub(".*?([0-9]+)$", "\1", numfields)),
function(flds) employ.data[ complete.cases(subset(employ.data, select = flds)), ])
out
# $`1`
# employee salary1 salary2 date1 date2
# 2 Peter Gynn 20400 NA 2008-03-25 <NA>
# 3 Jolie Hope 26800 78765 2007-03-14 2007-03-14
# $`2`
# employee salary1 salary2 date1 date2
# 1 John Doe NA 29045 <NA> 2010-11-01
# 3 Jolie Hope 26800 78765 2007-03-14 2007-03-14
这将动态查找所有带编号的字段,但不可否认它不强制“成对”。
non_na
函数returns在名称以 i 结尾的列中没有缺失值的行。它首先将这些列名称定义为 cn,然后使用 complete.cases 定义一个逻辑向量,指示哪些行在这些列中没有 NA,然后 returns 来自 employ.data.[=16 的那些行=]
假设列中唯一的数字位于名称的末尾,并且唯一的此类数字定义了可能的后缀。词干是去除后缀后的那些唯一名称。
我们假设第 1 列将被排除在该计算之外。我们使用 gsub/unique 来定义后缀和词干。或者硬编码 suffixes <- as.character(1:2)
和 stems <- c("salary", "date")
.
最后 运行 non_na 在每个后缀上创建一个列表,其 i 组件包含一个数据框,其中的行对应于 i。 L[[i]]
将是第 i 个数据框。
non_na <- function(i) {
cn <- paste0(stems, i)
employ.data[complete.cases(employ.data[cn]), ]
}
nms <- names(employ.data)[-1]
suffixes <- unique(gsub("\D", "", nms)) # c("1", "2")
stems <- unique(gsub("\d", "", nms)) # c("salary", "date")
L <- Map(non_na, suffixes); L
给予:
$`1`
employee salary1 salary2 date1 date2
2 Peter Gynn 20400 NA 2008-03-25 <NA>
3 Jolie Hope 26800 78765 2007-03-14 2007-03-14
$`2`
employee salary1 salary2 date1 date2
1 John Doe NA 29045 <NA> 2010-11-01
3 Jolie Hope 26800 78765 2007-03-14 2007-03-14
如果多个变量(以相同后缀结尾)不包含 NA,我想对 R 数据帧进行子集化。
employee <- c('John Doe','Peter Gynn','Jolie Hope')
salary1 <- c(NA, 20400, 26800)
salary2 <- c(29045, NA, 78765)
date1 <- as.Date(c(NA,'2008-3-25','2007-3-14'))
date2 <- as.Date(c('2010-11-1',NA,'2007-3-14'))
employ.data <- data.frame(employee, salary1, salary2, date1, date2)
for (i in 1:2) {
assign("employ.data", i, subset(employ.data, !is.na(employ.data$date[i]) & !is.na(employ.data$salary[i])))
}
最终结果有望产生两个独立的数据帧,如下所示:
employ.data1:
| employee | salary1 | salary2 | date1 | date2 |
| Peter Gynn | 20400 | NA | 2008-03-25 | NA |
| Jolie Hope | 26800 | 78765 | 2007-03-14 | 2007-03-14 |
employ.data2:
| employee | salary1 | salary2 | date1 | date2 |
| John Doe | NA | 29045 | NA | 2010-11-01 |
| Jolie Hope | 26800 | 78765 | 2007-03-14 | 2007-03-14 |
提前致谢!
(预先:处理 list of frames 通常比使用 assign
动态创建对象更好。)
numfields <- grep("[0-9]+$", colnames(employ.data), value = TRUE)
split(numfields, gsub(".*?([0-9]+)$", "\1", numfields))
# $`1`
# [1] "salary1" "date1"
# $`2`
# [1] "salary2" "date2"
out <- lapply(split(numfields, gsub(".*?([0-9]+)$", "\1", numfields)),
function(flds) employ.data[ complete.cases(subset(employ.data, select = flds)), ])
out
# $`1`
# employee salary1 salary2 date1 date2
# 2 Peter Gynn 20400 NA 2008-03-25 <NA>
# 3 Jolie Hope 26800 78765 2007-03-14 2007-03-14
# $`2`
# employee salary1 salary2 date1 date2
# 1 John Doe NA 29045 <NA> 2010-11-01
# 3 Jolie Hope 26800 78765 2007-03-14 2007-03-14
这将动态查找所有带编号的字段,但不可否认它不强制“成对”。
non_na
函数returns在名称以 i 结尾的列中没有缺失值的行。它首先将这些列名称定义为 cn,然后使用 complete.cases 定义一个逻辑向量,指示哪些行在这些列中没有 NA,然后 returns 来自 employ.data.[=16 的那些行=]
假设列中唯一的数字位于名称的末尾,并且唯一的此类数字定义了可能的后缀。词干是去除后缀后的那些唯一名称。
我们假设第 1 列将被排除在该计算之外。我们使用 gsub/unique 来定义后缀和词干。或者硬编码 suffixes <- as.character(1:2)
和 stems <- c("salary", "date")
.
最后 运行 non_na 在每个后缀上创建一个列表,其 i 组件包含一个数据框,其中的行对应于 i。 L[[i]]
将是第 i 个数据框。
non_na <- function(i) {
cn <- paste0(stems, i)
employ.data[complete.cases(employ.data[cn]), ]
}
nms <- names(employ.data)[-1]
suffixes <- unique(gsub("\D", "", nms)) # c("1", "2")
stems <- unique(gsub("\d", "", nms)) # c("salary", "date")
L <- Map(non_na, suffixes); L
给予:
$`1`
employee salary1 salary2 date1 date2
2 Peter Gynn 20400 NA 2008-03-25 <NA>
3 Jolie Hope 26800 78765 2007-03-14 2007-03-14
$`2`
employee salary1 salary2 date1 date2
1 John Doe NA 29045 <NA> 2010-11-01
3 Jolie Hope 26800 78765 2007-03-14 2007-03-14