我正在跟进这个问题。我在下面LIST
的数据帧是由我的data
.但是,此LIST
缺少原始data
中可用的paper
列(始终提供缺少列的名称)。
我想知道如何将缺失的paper
列放回LIST
以实现我在下面的DESIRED_LIST
?
我尝试了此答案(lapply(LIST, function(x)data[do.call(paste, data[names(x)]) %in% do.call(paste, x),])
)中建议的解决方案,但它没有产生我的DESIRED_LIST
。
一个基本R或整洁的解决方案是值得赞赏的。
可重现的数据和代码如下。
m2="
paper study sample comp ES bar
1 1 1 1 1 7
1 2 2 2 2 6
1 2 3 3 3 5
2 3 4 4 4 4
2 3 4 4 5 3
2 3 4 5 6 2
2 3 4 5 7 1"
data <- read.table(text=m2,h=T)
LIST <- list(data.frame(study=1 ,sample=1 ,comp=1),
data.frame(study=rep(3,4),sample=rep(4,4),comp=c(4,4,5,5)),
data.frame(study=c(2,2) ,sample=c(2,3) ,comp=c(2,3)))
DESIRED_LIST <- list(data.frame(paper=1 ,study=1 ,sample=1 ,comp=1),
data.frame(paper=rep(2,4),study=rep(3,4),sample=rep(4,4),comp=c(4,4,5,5)),
data.frame(paper=rep(1,2),study=c(2,2) ,sample=c(2,3) ,comp=c(2,3)))
- 请使用软件包找到解决方案
data.table
.这是你要找的吗?
Reprex 1
library(data.table)
cols_to_remove <- c("ES")
split(setDT(data)[, (cols_to_remove) := NULL], by = c("paper", "study"))
#> $`1.1`
#> paper study sample comp
#> 1: 1 1 1 1
#>
#> $`1.2`
#> paper study sample comp
#> 1: 1 2 2 2
#> 2: 1 2 3 3
#>
#> $`2.3`
#> paper study sample comp
#> 1: 2 3 4 4
#> 2: 2 3 4 4
#> 3: 2 3 4 5
#> 4: 2 3 4 5
创建于 2021-11-06 由 reprex 软件包 (v2.0.1)
<小时 />编辑
- 请找到带有包的解决方案 2
dplyr
Reprex 2
library(dplyr)
drop.cols <- c("ES")
data %>%
group_by(paper, study) %>%
select(-drop.cols) %>%
group_split()
#> <list_of<
#> tbl_df<
#> paper : integer
#> study : integer
#> sample: integer
#> comp : integer
#> >
#> >[3]>
#> [[1]]
#> # A tibble: 1 x 4
#> paper study sample comp
#> <int> <int> <int> <int>
#> 1 1 1 1 1
#>
#> [[2]]
#> # A tibble: 2 x 4
#> paper study sample comp
#> <int> <int> <int> <int>
#> 1 1 2 2 2
#> 2 1 2 3 3
#>
#> [[3]]
#> # A tibble: 4 x 4
#> paper study sample comp
#> <int> <int> <int> <int>
#> 1 2 3 4 4
#> 2 2 3 4 4
#> 3 2 3 4 5
#> 4 2 3 4 5
创建于 2021-11-07 由 reprex 软件包 (v2.0.1)
考虑ave
创建一个分组列(由于重复的行),然后运行迭代merge
。
DESIRED_LIST_SO <- lapply(
LIST,
function(df) merge(
transform(data, grp = ave(paper, paper, study, sample, comp, FUN=seq_along)),
transform(df, grp = ave(study, study, sample, comp, FUN=seq_along)),
by=c("study", "sample", "comp", "grp")
)[c("paper", "study", "sample", "comp")]
)
all.equal(DESIRED_LIST, DESIRED_LIST_SO)
[1] TRUE
(请考虑将唯一标识符、ES
和bar
保留在所需列表中,以避免重复行。
tidyverse
解决方案。首先,创建一个查找表data2
,其中包含四个目标列。mutate(across(.fns = as.numeric))
是使列类型保持一致。可能不需要。其次,使用map
将left_join
应用于LIST
中的所有数据框。LIST2
和DESIRED_LIST
是完全相同的。
data2 <- data %>%
distinct(paper, study, sample, comp) %>%
mutate(across(.fns = as.numeric))
LIST2 <- map(LIST, function(x){
x2 <- x %>%
left_join(data2, by = names(x)) %>%
select(all_of(names(data2)))
return(x2)
})
# Check if the results are the same
identical(DESIRED_LIST, LIST2)
# [1] TRUE