如何根据另一行中的范围对 R 中的列表进行条件子集
How to conditional subset a list in R based on range in another row
这个问题在某种程度上与我 14 天前问的另一个问题有关。
这里的不同之处在于,我需要对行而不是列进行子集化,我无法做到这一点。
我已经将 100 多个相等的 .xls 文件(每个 10 页)导入到 R 中的列表中。我现在正试图获取我需要的信息。文件中的数据高度非结构化。
我创建了一些玩具数据来展示我想要的。
list3 <- list(data.frame(depth = c(NA,NA,NA,1,2,3,4,5),
col1 = c(NA,NA,"black",NA,"x",NA,NA,NA),
col2 = c(NA,NA,"blue",NA,NA,"x",NA,NA),
col3 = c(NA,NA,"white","x",NA,NA,NA,NA),
col4 = c(NA,NA,"grey",NA,NA,NA,"x",NA),
col5 = c(NA,NA,"yellow",NA,NA,NA,NA,"x")))
list4 <- list(data.frame(depth = c(NA,NA,NA,1,2,3,4,5),
col1 = c(NA,NA,"black",NA,NA,"x",NA,NA),
col2 = c(NA,NA,"blue",NA,NA,NA,"x",NA),
col3 = c(NA,NA,"white","x",NA,NA,NA,NA),
col4 = c(NA,NA,"grey",NA,"x",NA,NA,NA),
col5 = c(NA,NA,"yellow",NA,NA,NA,NA,"x")))
list5 <- list(data.frame(depth = c(NA,NA,NA,1,2,3,4,5),
col1 = c(NA,NA,"black",NA,"x","x",NA,NA),
col2 = c(NA,NA,"blue",NA,NA,NA,"x",NA),
col3 = c(NA,NA,"white","x",NA,NA,NA,NA),
col4 = c(NA,NA,"grey",NA,NA,NA,NA,NA),
col5 = c(NA,NA,"yellow",NA,NA,NA,NA,"x")))
my_list <- list(list3,list4,list5)
desired_result <- data.frame(depth = c(1,2,3,4,5,1,2,3,4,5,1,2,3,4,5),
color = c("white","black","blue","grey","yellow",
"white","grey","black","blue","yellow",
"white","black","black","blue","yellow"))
正如我在上一个问题中提到的,数据是高度非结构化的,因此我需要一个基于范围子集的解决方案。
我需要遍历我的列表。到目前为止,我已经成功地 purrr:map 做到了。但是这个我好像想不通。
我需要 link 在我所有文件的每个深度上找到的颜色。结果不需要在数据帧中,每个深度的向量就可以了。
我希望有一个 purrr 解决方案,但谢天谢地,一切都被接受了。
试试这个:
library(purrr)
library(dplyr)
my_fun <-function(x){
depth <- x %>% summarise(across(.cols = starts_with("col"),.fns=~depth[which(.=="x")])) %>%
as.numeric()
color <- select(x,starts_with("col"))[3,] %>% as.character(.)
data.frame(depth,color) %>% arrange(depth)
}
map(my_list,function(l)do.call("rbind",map(l,my_fun))) %>% do.call("rbind",.)
输出:
# depth color
# 1 1 white
# 2 2 black
# 3 3 blue
# 4 4 grey
# 5 5 yellow
# 6 1 white
# 7 2 grey
# 8 3 black
# 9 4 blue
# 10 5 yellow
评论中给出的附加要求
你的my_list
竟然没有名字!所以试试这个语法
library(janitor)
imap_dfr(my_list, ~(.x[[1]] %>% mutate(across(starts_with("col"), ~ifelse(. == "x", depth, .))) %>%
select(-depth) %>% row_to_names(3) %>% ungroup() %>%
pivot_longer(everything(), names_to = "color", values_to = "depth", values_drop_na = T) %>%
mutate(list_name = .y)))
# A tibble: 15 x 3
color depth list_name
<chr> <chr> <int>
1 white 1 1
2 black 2 1
3 blue 3 1
4 grey 4 1
5 yellow 5 1
6 white 1 2
7 grey 2 2
8 black 3 2
9 blue 4 2
10 yellow 5 2
11 white 1 3
12 black 2 3
13 black 3 3
14 blue 4 3
15 yellow 5 3
如果列表包含名称,则输出将包含名称,否则将包含列表的索引号。建议使用 imap_dfr
。这里假设第三列包含颜色名称。
这个问题在某种程度上与我 14 天前问的另一个问题有关。
这里的不同之处在于,我需要对行而不是列进行子集化,我无法做到这一点。
我已经将 100 多个相等的 .xls 文件(每个 10 页)导入到 R 中的列表中。我现在正试图获取我需要的信息。文件中的数据高度非结构化。
我创建了一些玩具数据来展示我想要的。
list3 <- list(data.frame(depth = c(NA,NA,NA,1,2,3,4,5),
col1 = c(NA,NA,"black",NA,"x",NA,NA,NA),
col2 = c(NA,NA,"blue",NA,NA,"x",NA,NA),
col3 = c(NA,NA,"white","x",NA,NA,NA,NA),
col4 = c(NA,NA,"grey",NA,NA,NA,"x",NA),
col5 = c(NA,NA,"yellow",NA,NA,NA,NA,"x")))
list4 <- list(data.frame(depth = c(NA,NA,NA,1,2,3,4,5),
col1 = c(NA,NA,"black",NA,NA,"x",NA,NA),
col2 = c(NA,NA,"blue",NA,NA,NA,"x",NA),
col3 = c(NA,NA,"white","x",NA,NA,NA,NA),
col4 = c(NA,NA,"grey",NA,"x",NA,NA,NA),
col5 = c(NA,NA,"yellow",NA,NA,NA,NA,"x")))
list5 <- list(data.frame(depth = c(NA,NA,NA,1,2,3,4,5),
col1 = c(NA,NA,"black",NA,"x","x",NA,NA),
col2 = c(NA,NA,"blue",NA,NA,NA,"x",NA),
col3 = c(NA,NA,"white","x",NA,NA,NA,NA),
col4 = c(NA,NA,"grey",NA,NA,NA,NA,NA),
col5 = c(NA,NA,"yellow",NA,NA,NA,NA,"x")))
my_list <- list(list3,list4,list5)
desired_result <- data.frame(depth = c(1,2,3,4,5,1,2,3,4,5,1,2,3,4,5),
color = c("white","black","blue","grey","yellow",
"white","grey","black","blue","yellow",
"white","black","black","blue","yellow"))
正如我在上一个问题中提到的,数据是高度非结构化的,因此我需要一个基于范围子集的解决方案。
我需要遍历我的列表。到目前为止,我已经成功地 purrr:map 做到了。但是这个我好像想不通。
我需要 link 在我所有文件的每个深度上找到的颜色。结果不需要在数据帧中,每个深度的向量就可以了。
我希望有一个 purrr 解决方案,但谢天谢地,一切都被接受了。
试试这个:
library(purrr)
library(dplyr)
my_fun <-function(x){
depth <- x %>% summarise(across(.cols = starts_with("col"),.fns=~depth[which(.=="x")])) %>%
as.numeric()
color <- select(x,starts_with("col"))[3,] %>% as.character(.)
data.frame(depth,color) %>% arrange(depth)
}
map(my_list,function(l)do.call("rbind",map(l,my_fun))) %>% do.call("rbind",.)
输出:
# depth color
# 1 1 white
# 2 2 black
# 3 3 blue
# 4 4 grey
# 5 5 yellow
# 6 1 white
# 7 2 grey
# 8 3 black
# 9 4 blue
# 10 5 yellow
评论中给出的附加要求
你的my_list
竟然没有名字!所以试试这个语法
library(janitor)
imap_dfr(my_list, ~(.x[[1]] %>% mutate(across(starts_with("col"), ~ifelse(. == "x", depth, .))) %>%
select(-depth) %>% row_to_names(3) %>% ungroup() %>%
pivot_longer(everything(), names_to = "color", values_to = "depth", values_drop_na = T) %>%
mutate(list_name = .y)))
# A tibble: 15 x 3
color depth list_name
<chr> <chr> <int>
1 white 1 1
2 black 2 1
3 blue 3 1
4 grey 4 1
5 yellow 5 1
6 white 1 2
7 grey 2 2
8 black 3 2
9 blue 4 2
10 yellow 5 2
11 white 1 3
12 black 2 3
13 black 3 3
14 blue 4 3
15 yellow 5 3
如果列表包含名称,则输出将包含名称,否则将包含列表的索引号。建议使用 imap_dfr
。这里假设第三列包含颜色名称。