根据多列和每个嵌套数据框的 select 特定列将数据框拆分为多个数据框的列表
Split dataframe into list of multiple dataframes based on multiple columns and select specific columns for each nested dataframe
我有一个这样的数据框:
|DOI | WoS| Scopus| Dim| WoS_Year| Scopus_Year| Dim_Year|
|:-----------------------------|---:|------:|---:|--------:|-----------:|--------:|
|10.1515/jag-2017-0010 | NA| 1| 1| NA| 2017| 2017|
|10.1007/978-3-662-55771-6_9 | NA| NA| 1| NA| NA| 2020|
|10.1088/1361-6668/30/2/024004 | 1| 1| NA| 2017| 2017| NA|
|10.3390/ma12010124 | 1| 1| NA| 2019| 2019| NA|
|10.1002/ppsc.201700109 | 1| 1| 1| 2017| 2017| 2017|
我想把它分成一个包含 3 个数据帧的列表 (list_of_df
),其中:
- WoS:
list_of_df$WoS
应该有所有 DOI
和 WoS = 1
,以及类似于旧的列 Year
WoS_Year
;
- Scopus:
list_of_df$Scopus
应该包含所有具有 Scopus= 1
的 DOI
,以及一个类似于旧 Year
的列 Scopus_Year
;
- Dim:
list_of_df$Dim
应该有所有 DOI
有 Dim= 1
,和一列 Year
类似于旧的 Dim_Year
.
(实际上有多个以 WoS_*
或 Scopus_*
或 Dim_*
开头的列,我希望每个列都保留在新的相应 list_of_df
中,但是删除起始字符串,如 WoS_
等
例如,所有 starting_with("Scopus_")
的列都应该在 list_of_df$Scopus
中,但列名称中没有 Scopus_
。)
实现此目标的最佳方法是什么?
我对 list_of_df <- split(df, with(df, interaction(WoS,Scopus,Dim)), drop = TRUE)
或 dplyr::nest(df, WoS:Dim)
的尝试没有结果...
感谢您的帮助!
> dput(df)
structure(list(DOI = c("10.1515/jag-2017-0010", "10.1007/978-3-662-55771-6_9",
"10.1088/1361-6668/30/2/024004", "10.3390/ma12010124", "10.1002/ppsc.201700109"
), WoS = c(NA, NA, 1L, 1L, 1L), Scopus = c(1L, NA, 1L, 1L, 1L
), Dim = c(1L, 1L, NA, NA, 1L), WoS_Year = c(NA, NA, 2017L, 2019L,
2017L), Scopus_Year = c(2017L, NA, 2017L, 2019L, 2017L), Dim_Year = c(2017L,
2020L, NA, NA, 2017L)), row.names = c(2186L, 9505L, 12281L, 11882L,
874L), class = "data.frame")
在基础 R 中你可以这样做:
df1 <- subset(reshape(df, matrix(2:ncol(df),2, byrow=TRUE), dir="long", idvar = "DOI",
times = c("WoS","Scopus","Dim")), WoS==1)
rownames(df1)<-NULL
split(df1, df1$time)
$Dim
DOI time WoS WoS_Year
8 10.1515/jag-2017-0010 Dim 1 2017
9 10.1007/978-3-662-55771-6_9 Dim 1 2020
10 10.1002/ppsc.201700109 Dim 1 2017
$Scopus
DOI time WoS WoS_Year
4 10.1515/jag-2017-0010 Scopus 1 2017
5 10.1088/1361-6668/30/2/024004 Scopus 1 2017
6 10.3390/ma12010124 Scopus 1 2019
7 10.1002/ppsc.201700109 Scopus 1 2017
$WoS
DOI time WoS WoS_Year
1 10.1088/1361-6668/30/2/024004 WoS 1 2017
2 10.3390/ma12010124 WoS 1 2019
3 10.1002/ppsc.201700109 WoS 1 2017
您可以更改列名以符合您的需要
另一种方式:
lapply(split.default(df[-1],sub("_.*","",names(df[-1]))),
function(x)na.omit(cbind(df[1], x)[x[[1]]==1,]))
$Dim
DOI Dim Dim_Year
2186 10.1515/jag-2017-0010 1 2017
9505 10.1007/978-3-662-55771-6_9 1 2020
874 10.1002/ppsc.201700109 1 2017
$Scopus
DOI Scopus Scopus_Year
2186 10.1515/jag-2017-0010 1 2017
12281 10.1088/1361-6668/30/2/024004 1 2017
11882 10.3390/ma12010124 1 2019
874 10.1002/ppsc.201700109 1 2017
$WoS
DOI WoS WoS_Year
12281 10.1088/1361-6668/30/2/024004 1 2017
11882 10.3390/ma12010124 1 2019
874 10.1002/ppsc.201700109 1 2017
另外一个在 base R 中,如果这是预期的输出
res=list()
for (k in c("WoS","Scopus","Dim")) {
res[[k]]=df[df[,k]==1 & !is.na(df[,k]),grepl(k,colnames(df)) | c(TRUE,rep(FALSE,ncol(df)-1))]
colnames(res[[k]])=gsub(paste0(k,"_"),"",colnames(res[[k]]))
}
$WoS
DOI WoS Year
12281 10.1088/1361-6668/30/2/024004 1 2017
11882 10.3390/ma12010124 1 2019
874 10.1002/ppsc.201700109 1 2017
$Scopus
DOI Scopus Year
2186 10.1515/jag-2017-0010 1 2017
12281 10.1088/1361-6668/30/2/024004 1 2017
11882 10.3390/ma12010124 1 2019
874 10.1002/ppsc.201700109 1 2017
$Dim
DOI Dim Year
2186 10.1515/jag-2017-0010 1 2017
9505 10.1007/978-3-662-55771-6_9 1 2020
874 10.1002/ppsc.201700109 1 2017
我有一个这样的数据框:
|DOI | WoS| Scopus| Dim| WoS_Year| Scopus_Year| Dim_Year|
|:-----------------------------|---:|------:|---:|--------:|-----------:|--------:|
|10.1515/jag-2017-0010 | NA| 1| 1| NA| 2017| 2017|
|10.1007/978-3-662-55771-6_9 | NA| NA| 1| NA| NA| 2020|
|10.1088/1361-6668/30/2/024004 | 1| 1| NA| 2017| 2017| NA|
|10.3390/ma12010124 | 1| 1| NA| 2019| 2019| NA|
|10.1002/ppsc.201700109 | 1| 1| 1| 2017| 2017| 2017|
我想把它分成一个包含 3 个数据帧的列表 (list_of_df
),其中:
- WoS:
list_of_df$WoS
应该有所有DOI
和WoS = 1
,以及类似于旧的列Year
WoS_Year
; - Scopus:
list_of_df$Scopus
应该包含所有具有Scopus= 1
的DOI
,以及一个类似于旧Year
的列Scopus_Year
; - Dim:
list_of_df$Dim
应该有所有DOI
有Dim= 1
,和一列Year
类似于旧的Dim_Year
.
(实际上有多个以 WoS_*
或 Scopus_*
或 Dim_*
开头的列,我希望每个列都保留在新的相应 list_of_df
中,但是删除起始字符串,如 WoS_
等
例如,所有 starting_with("Scopus_")
的列都应该在 list_of_df$Scopus
中,但列名称中没有 Scopus_
。)
实现此目标的最佳方法是什么?
我对 list_of_df <- split(df, with(df, interaction(WoS,Scopus,Dim)), drop = TRUE)
或 dplyr::nest(df, WoS:Dim)
的尝试没有结果...
感谢您的帮助!
> dput(df)
structure(list(DOI = c("10.1515/jag-2017-0010", "10.1007/978-3-662-55771-6_9",
"10.1088/1361-6668/30/2/024004", "10.3390/ma12010124", "10.1002/ppsc.201700109"
), WoS = c(NA, NA, 1L, 1L, 1L), Scopus = c(1L, NA, 1L, 1L, 1L
), Dim = c(1L, 1L, NA, NA, 1L), WoS_Year = c(NA, NA, 2017L, 2019L,
2017L), Scopus_Year = c(2017L, NA, 2017L, 2019L, 2017L), Dim_Year = c(2017L,
2020L, NA, NA, 2017L)), row.names = c(2186L, 9505L, 12281L, 11882L,
874L), class = "data.frame")
在基础 R 中你可以这样做:
df1 <- subset(reshape(df, matrix(2:ncol(df),2, byrow=TRUE), dir="long", idvar = "DOI",
times = c("WoS","Scopus","Dim")), WoS==1)
rownames(df1)<-NULL
split(df1, df1$time)
$Dim
DOI time WoS WoS_Year
8 10.1515/jag-2017-0010 Dim 1 2017
9 10.1007/978-3-662-55771-6_9 Dim 1 2020
10 10.1002/ppsc.201700109 Dim 1 2017
$Scopus
DOI time WoS WoS_Year
4 10.1515/jag-2017-0010 Scopus 1 2017
5 10.1088/1361-6668/30/2/024004 Scopus 1 2017
6 10.3390/ma12010124 Scopus 1 2019
7 10.1002/ppsc.201700109 Scopus 1 2017
$WoS
DOI time WoS WoS_Year
1 10.1088/1361-6668/30/2/024004 WoS 1 2017
2 10.3390/ma12010124 WoS 1 2019
3 10.1002/ppsc.201700109 WoS 1 2017
您可以更改列名以符合您的需要
另一种方式:
lapply(split.default(df[-1],sub("_.*","",names(df[-1]))),
function(x)na.omit(cbind(df[1], x)[x[[1]]==1,]))
$Dim
DOI Dim Dim_Year
2186 10.1515/jag-2017-0010 1 2017
9505 10.1007/978-3-662-55771-6_9 1 2020
874 10.1002/ppsc.201700109 1 2017
$Scopus
DOI Scopus Scopus_Year
2186 10.1515/jag-2017-0010 1 2017
12281 10.1088/1361-6668/30/2/024004 1 2017
11882 10.3390/ma12010124 1 2019
874 10.1002/ppsc.201700109 1 2017
$WoS
DOI WoS WoS_Year
12281 10.1088/1361-6668/30/2/024004 1 2017
11882 10.3390/ma12010124 1 2019
874 10.1002/ppsc.201700109 1 2017
另外一个在 base R 中,如果这是预期的输出
res=list()
for (k in c("WoS","Scopus","Dim")) {
res[[k]]=df[df[,k]==1 & !is.na(df[,k]),grepl(k,colnames(df)) | c(TRUE,rep(FALSE,ncol(df)-1))]
colnames(res[[k]])=gsub(paste0(k,"_"),"",colnames(res[[k]]))
}
$WoS
DOI WoS Year
12281 10.1088/1361-6668/30/2/024004 1 2017
11882 10.3390/ma12010124 1 2019
874 10.1002/ppsc.201700109 1 2017
$Scopus
DOI Scopus Year
2186 10.1515/jag-2017-0010 1 2017
12281 10.1088/1361-6668/30/2/024004 1 2017
11882 10.3390/ma12010124 1 2019
874 10.1002/ppsc.201700109 1 2017
$Dim
DOI Dim Year
2186 10.1515/jag-2017-0010 1 2017
9505 10.1007/978-3-662-55771-6_9 1 2020
874 10.1002/ppsc.201700109 1 2017