我有以下列表Y和列表Z:
例如:
列出Y:
[[1]]
[[1]]$`1`
V1 V2
1 1 1
2 1 2
3 2 1
4 2 2
[[1]]$`2`
V1 V2
9 5 5
10 5 6
[[1]]$`3`
V1 V2
5 10 1
6 10 2
7 11 1
8 11 2
[[2]]
[[2]]$`1`
V1 V2
1 1 1
2 1 2
3 2 1
4 2 2
9 5 5
10 5 6
[[2]]$`2`
V1 V2
5 10 1
7 11 1
8 11 2
[[2]]$`3`
V1 V2
6 10 2
列出Z:
[[1]]
[[1]]$`1`
[1] 2 1
[[1]]$`2`
[1] 5 5
[[1]]$`3`
[1] 10 1
[[2]]
[[2]]$`1`
[1] 1 1
[[2]]$`2`
[1] 11 1
[[2]]$`3`
[1] 10 2
我想在列表Y和列表Z之间进行计算:
(|y-z|+|y-z|)^2
这样ListY [[1]] $ 1
中的所有元素减去ListZ [[1]] $ 1
下,
ListY [[1]] $ 2
中的所有元素减去ListZ [[1]] $ 2
下一步,
ListY [[1]] $ 3
中的所有元素减去ListZ [[1]] $ 3
同样适用于ListY [[2]]和List Z [[2]]
Expected output for (|y-z| + |y-z|)^2 between ListY[[1]] and ListZ[[1]]:
>
$`1`
1 2 3 4
1 2 0 1
$`2`
9 10
0 1
$`3`
5 6 7 8
0 1 1 2
Expected output for (|y-z| + |y-z|)^2 between ListY[[2]] and ListZ[[2]]:
>
$`1`
1 2 3 4 5 9 10
1 0 0 1
$`2`
5 7 8
1 0 1
$`3`
6
0
例如,这就是我获得预期结果的方式:
Y[[1]]
[[1]]$`1`
V1 V2
1 1 1
2 1 2
3 2 1
4 2 2
[[1]]
[[1]]$`1`
[1] 2 1
(|1-2|+|1-1|)^2 = 1
(|1-2|+|2-1|)^2 = 4
(|2-2|+|1-1|)^2 = 0
(|2-2|+|2-1|)^2 = 1
$`1`
1 2 3 4 5 9 10
1 4 0 1
我怎样才能在R?
中这样做答案 0 :(得分:2)
我认为这应该可以解决您的问题。不确定你给出了正确的预期输出,因为我得到了不同的输出。
<强>解释强>:
最外面的mapply
将通过Y
和Z
,u,v
将被分配Y[[1],Z[[1]]
,然后在第二次迭代中分配Y[[2],Z[[2]]
。
内部mapply
将从$1
和$2
获取$3
,u
,v
的相应值。因此 a
将获得data.frame
,而 b
将被分配vector
。然后,您可以使用apply逐行迭代,并以矢量化方式进行计算。
试试这个:
mapply(function(u,v){
result=mapply(function(a,b){
apply(X = a,MARGIN = 1,
function(c,d){
sum(abs(c-d))^2},b)
},u,v,SIMPLIFY = TRUE)
return(result)
},
Y,Z,SIMPLIFY = FALSE)
[[1]]
[[1]]$`1`
[1] 1 4 0 1
[[1]]$`2`
[1] 0 1
[[1]]$`3`
[1] 0 1 1 4
[[2]]
[[2]]$`1`
[1] 0 1 1 4 64 81
[[2]]$`2`
[1] 1 0 1
[[2]]$`3`
[1] 0
答案 1 :(得分:2)
我决定以不同的方式做这项工作,作为大脑的早晨锻炼。
# let's first partially flatten the lists:
y2 <- lapply(unlist(y, recursive=FALSE), as.matrix)
z2 <- unlist(z, recursive=FALSE)
# and the *flat* answer, using sweep and rowSums:
mapply(function(a,b) rowSums(abs(sweep(a,2,b)))^2, y2, z2)
这里有一个缺陷:新数据结构与旧数据结构不同。可以用嵌套的mapply来解决它:
mapply(function(ex, why) mapply(function(a,b) rowSums(abs(sweep(a,2,b)))^2, ex, why), y,z, SIMPLIFY=FALSE)
..但是首先将它定义为一个函数然后将其重新映射然后再次进行mapplyit会更好:
doit <- function(a,b) rowSums(abs(sweep(a,2,b)))^2
mapplyit <- function(a,b) mapply(doit, a,b)
mapply(mapplyit, y,z, SIMPLIFY=FALSE)
......结果是:
[[1]]
[[1]][[1]]
1 2 3 4
1 4 0 1
[[1]][[2]]
9 10
0 1
[[1]][[3]]
5 6 7 8
0 1 1 4
[[2]]
[[2]][[1]]
1 2 3 4 9 10
0 1 1 4 64 81
[[2]][[2]]
5 7 8
1 0 1
[[2]][[3]]
6
0
......以及数据结构(OP应该以可重现的方式提供: - )
y <- list(
list(
read.table(text="V1 V2
1 1 1
2 1 2
3 2 1
4 2 2"),
read.table(text="V1 V2
9 5 5
10 5 6"),
read.table(text="V1 V2
5 10 1
6 10 2
7 11 1
8 11 2")),
list(
read.table(text="V1 V2
1 1 1
2 1 2
3 2 1
4 2 2
9 5 5
10 5 6"),
read.table(text="V1 V2
5 10 1
7 11 1
8 11 2"),
read.table(text="V1 V2
6 10 2")))
z <- list(
list(
c(2, 1),
c(5,5),
c(10,1)),
list(
c(1,1),
c(11,1),
c(10,2)
))