Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
tidyverse:绑定相同维度的列表元素_R_Dplyr_Tidyverse_Reduce_Purrr - Fatal编程技术网

tidyverse:绑定相同维度的列表元素

tidyverse:绑定相同维度的列表元素,r,dplyr,tidyverse,reduce,purrr,R,Dplyr,Tidyverse,Reduce,Purrr,使用reduce(bind\u cols),可以组合相同维度的列表元素。但是,我想知道如何从可能具有不同维度元素的列表中只组合相同维度(可能以某种方式指定维度)的元素 library(tidyverse) df1 <- data.frame(A1 = 1:10, A2 = 10:1) df2 <- data.frame(B = 11:30) df3 <- data.frame(C = 31:40) ls1 <- list(df1, df3) ls1 [[1]]

使用
reduce(bind\u cols)
,可以组合相同维度的列表元素。但是,我想知道如何从可能具有不同维度元素的列表中只组合相同维度(可能以某种方式指定维度)的元素

library(tidyverse)

df1 <- data.frame(A1 = 1:10, A2 = 10:1)
df2 <- data.frame(B = 11:30)
df3 <- data.frame(C = 31:40)

ls1 <- list(df1, df3)
ls1

[[1]]
   A1 A2
1   1 10
2   2  9
3   3  8
4   4  7
5   5  6
6   6  5
7   7  4
8   8  3
9   9  2
10 10  1

[[2]]
    C
1  31
2  32
3  33
4  34
5  35
6  36
7  37
8  38
9  39
10 40

ls1 %>%
  reduce(bind_cols)

  A1 A2  C
1   1 10 31
2   2  9 32
3   3  8 33
4   4  7 34
5   5  6 35
6   6  5 36
7   7  4 37
8   8  3 38
9   9  2 39
10 10  1 40

ls2 <- list(df1, df2, df3)
ls2

[[1]]
   A1 A2
1   1 10
2   2  9
3   3  8
4   4  7
5   5  6
6   6  5
7   7  4
8   8  3
9   9  2
10 10  1

[[2]]
    B
1  11
2  12
3  13
4  14
5  15
6  16
7  17
8  18
9  19
10 20
11 21
12 22
13 23
14 24
15 25
16 26
17 27
18 28
19 29
20 30

[[3]]
    C
1  31
2  32
3  33
4  34
5  35
6  36
7  37
8  38
9  39
10 40


ls2 %>%
  reduce(bind_cols)

Error: Can't recycle `..1` (size 10) to match `..2` (size 20).
Run `rlang::last_error()` to see where the error occurred.
库(tidyverse)
df1一个选项可以是:

map(split(lst, map_int(lst, NROW)), bind_cols)

$`10`
   A1 A2  C
1   1 10 31
2   2  9 32
3   3  8 33
4   4  7 34
5   5  6 35
6   6  5 36
7   7  4 37
8   8  3 38
9   9  2 39
10 10  1 40

$`20`
    B
1  11
2  12
3  13
4  14
5  15
6  16
7  17
8  18
9  19
10 20
11 21
12 22
13 23
14 24
15 25
16 26
17 27
18 28
19 29
20 30

这里还有另一个
tidyverse
选项

我们基于
行号()
,在每个
data.frame
中创建一个虚拟ID,然后通过虚拟ID连接所有
data.frame
,然后删除虚拟ID

ls2 %>%
  map(., ~mutate(.x, id = row_number())) %>% 
  reduce(full_join, by = "id") %>% 
  select(-id)
这给了我们:

 A1 A2  B  C
1   1 10 11 31
2   2  9 12 32
3   3  8 13 33
4   4  7 14 34
5   5  6 15 35
6   6  5 16 36
7   7  4 17 37
8   8  3 18 38
9   9  2 19 39
10 10  1 20 40
11 NA NA 21 NA
12 NA NA 22 NA
13 NA NA 23 NA
14 NA NA 24 NA
15 NA NA 25 NA
16 NA NA 26 NA
17 NA NA 27 NA
18 NA NA 28 NA
19 NA NA 29 NA
20 NA NA 30 NA
你可以用-

n <- 1:max(sapply(ls2, nrow))
res <- do.call(cbind, lapply(ls2, `[`, n, ,drop = FALSE))
res

#     A1 A2  B  C
#1     1 10 11 31
#2     2  9 12 32
#3     3  8 13 33
#4     4  7 14 34
#5     5  6 15 35
#6     6  5 16 36
#7     7  4 17 37
#8     8  3 18 38
#9     9  2 19 39
#10   10  1 20 40
#NA   NA NA 21 NA
#NA.1 NA NA 22 NA
#NA.2 NA NA 23 NA
#NA.3 NA NA 24 NA
#NA.4 NA NA 25 NA
#NA.5 NA NA 26 NA
#NA.6 NA NA 27 NA
#NA.7 NA NA 28 NA
#NA.8 NA NA 29 NA
#NA.9 NA NA 30 NA

我们还可以从基本R使用
Reduce
函数:

lst <- list(df1, df2, df3)

# First we create id number for each underlying data set

lst |>
  lapply(\(x) {x$id <- 1:nrow(x); 
  x
 }
) -> ls2

Reduce(function(x, y) if(nrow(x) == nrow(y)){
  merge(x, y, by = "id")
} else {
  x
}, ls2)


   id A1 A2  C
1   1  1 10 31
2   2  2  9 32
3   3  3  8 33
4   4  4  7 34
5   5  5  6 35
6   6  6  5 36
7   7  7  4 37
8   8  8  3 38
9   9  9  2 39
10 10 10  1 40
lst
lapply(\(x){x$id ls2
如果(nrow(x)=nrow(y))减少(函数(x,y)){
合并(x,y,by=“id”)
}否则{
x
},ls2)
id A1 A2 C
1   1  1 10 31
2   2  2  9 32
3   3  3  8 33
4   4  4  7 34
5   5  5  6 35
6   6  6  5 36
7   7  7  4 37
8   8  8  3 38
9   9  9  2 39
10 10 10  1 40

我们可以使用
cbind.fill
rowr

library(rowr)
do.call(cbind.fill, c(ls2, fill = NA))

使用
tapply
+
sapply

tapply(
  ls2,
  sapply(ls2, nrow),
  function(x) do.call(cbind, x)
)
给予


如果要组合列表中的类似元素,也可以在
reduce
中使用
if
(案例:当列表中的第一项具有优先级时)

df1 4 7 34
#> 5   5  6 35
#> 6   6  5 36
#> 7   7  4 37
#> 8   8  3 38
#> 9   9  2 39
#> 10 10  1 40

由(v2.0.0)于2021-06-09创建

也许您可以用理想的
ls2%>%reduce(bind_cols)输出更新问题
?我不明白你的问题。你的预期输出是什么样子的?请查看我对@ianCampbell的编辑以了解我的实际列表,我收到了以下错误:
错误:结果1必须是一个整数,长度不为0
。请想一想。你有没有可能有一个空列表?将
nrow
更改为
nrow
map_int(lst,NROW)
中也适用于我的实际列表。谢谢,这也适用于空列表。@AnoushiravanR将类似于公认的解决方案,即获取行数并按行数拆分。在
base R
中,它将使用
lappy(拆分(ls2,sappy(ls2,NROW)),函数(x)do.call(cbind,x))
我没有收到。您可以使用
分组
绑定行
您知道这么多包,尊敬的!)
tapply(
  ls2,
  sapply(ls2, nrow),
  function(x) do.call(cbind, x)
)
$`10`
   A1 A2  C
1   1 10 31
2   2  9 32
3   3  8 33
4   4  7 34
5   5  6 35
6   6  5 36
7   7  4 37
8   8  3 38
9   9  2 39
10 10  1 40

$`20`
    B
1  11
2  12
3  13
4  14
5  15
6  16
7  17
8  18
9  19
10 20
11 21
12 22
13 23
14 24
15 25
16 26
17 27
18 28
19 29
20 30