Я хотел бы сделать итерацию с 2 списками.

В одном случае у меня есть один фрейм данных df1 и один вектор v1.

Мой воспроизводимый пример, как показано ниже.

df1 <- data.frame(n1 = c(2,2,0),
                 n2 = c(2,1,1),
                 n3 = c(0,1,1),
                 n4 = c(0,1,1))

v1 <- c(1,2,3)

Теперь я вычисляю значение (ses.value) для каждой строки, используя этот код.

x <- (v1 - apply(df1, 1, mean))/apply(df1,1,sd)

Допустим, у нас будет список из нескольких фреймов данных l1 и список векторов l2 (каждый список имеет одинаковое количество элементов). Теперь я хотел бы запустить цикл для этих списков, используя приведенный выше код (элемент l1 должен идти с элементом l2 с той же позицией).

# 3 dataframes and 3 vectors
df1 <- data.frame(n1 = c(2,2,0), n2 = c(2,1,1), n3 = c(0,1,1), n4 = c(0,1,1))
df2 <- data.frame(n1 = c(1,6,0), n2 = c(2,1,8), n3 = c(0,2,1), n4 = c(0,7,1))
df3 <- data.frame(n1 = c(1,6,0), n2 = c(9,1,5), n3 = c(4,2,1), n4 = c(0,7,2))

v1 <- c(1,2,3)
v2 <- c(2,3,4)
v3 <- c(4,5,6)

# list
l1 <- list(df1,df2,df3)
l2 <- list(v1,v2,v3)

Поскольку мои списки слишком велики, использование for loop может быть не такой уж хорошей идеей, какие-либо предложения с использованием lapply или чего-то подобного?

1
Anh 17 Сен 2021 в 21:31

2 ответа

Лучший ответ

Мы можем использовать Map, чтобы перебрать соответствующие элементы каждого list, а затем выполнить вычисление на основе кода OP

Map(function(x, y) (y - apply(x, 1, mean))/apply(x,1,sd), l1, l2)

-вывод

[[1]]
[1] 0.0 1.5 4.5

[[2]]
[1]  1.3055824 -0.3396831  0.4057513

[[3]]
[1] 0.1237179 0.3396831 1.8516402

Кроме того, если наборы данных действительно большие, используйте dapply из collapse, что более эффективно

library(collapse)
 Map(function(x, y) (y - dapply(x, MARGIN = 1,
     FUN = fmean))/dapply(x, MARGIN = 1, FUN = fsd), l1, l2)
1
akrun 17 Сен 2021 в 18:55

Поскольку ваши списки явно велики, вы, вероятно, могли бы извлечь выгоду из rowMeans2 и rowSds пакета matrixStats.

library(matrixStats)
Map(\(x, y) (y - rowMeans2(as.matrix(x))) / rowSds(as.matrix(x)), l1, l2)
# [[1]]
# [1] 0.0 1.5 4.5
# 
# [[2]]
# [1]  1.3055824 -0.3396831  0.4057513
# 
# [[3]]
# [1] 0.1237179 0.3396831 1.8516402

< EM> Данные:

l1 <- list(structure(list(n1 = c(2, 2, 0), n2 = c(2, 1, 1), n3 = c(0, 
1, 1), n4 = c(0, 1, 1)), class = "data.frame", row.names = c(NA, 
-3L)), structure(list(n1 = c(1, 6, 0), n2 = c(2, 1, 8), n3 = c(0, 
2, 1), n4 = c(0, 7, 1)), class = "data.frame", row.names = c(NA, 
-3L)), structure(list(n1 = c(1, 6, 0), n2 = c(9, 1, 5), n3 = c(4, 
2, 1), n4 = c(0, 7, 2)), class = "data.frame", row.names = c(NA, 
-3L)))

l2 <- list(c(1, 2, 3), c(2, 3, 4), c(4, 5, 6))
1
jay.sf 17 Сен 2021 в 18:50