gpt4 book ai didi

r - 简化双for循环

转载 作者:行者123 更新时间:2023-12-04 12:32:29 25 4
gpt4 key购买 nike

我有两个矩阵。矩阵 A 有 14 个变量(但我只对本练习中的五个变量感兴趣),矩阵 B 有五个变量。矩阵 A 有 250,000 个观测值,矩阵 B 有 23,000 个观测值。变量是非数字字符(文本)。

我的目标是用矩阵 B 第 4 列和第 5 列的信息填充矩阵 A 的第 9 列和第 10 列,如果矩阵 A 的第 1、2 和 8 列等同于矩阵 B 的第 1、2 和 3 列.

我编写的代码是一个双循环,运行大约需要 10 天。我正在寻找一种方法来简化代码,使其更高效并运行得更快(最好在几个小时内)。

代码如下:

    for (i in 1:nrow(matrix_b)) {
for (j in 1:nrow(matrix_a)) {
if (matrix_a[j,1]==matrix_b[i,1]) {
if (matrix_a[j,2]==matrix_b[i,2]) {
if (matrix_a[j,8]==matrix_b[i,3]) {
matrix_a[j,9]<-matrix_b[i,4]
matrix_a[j,10]<-matrix_b[i,5]
}
}
}
}
}

一个例子是:

    # Matrix A
[,1] [,2] [,8] [,9] [,10]
[1,] Z10 11 Nov 2012 Rocko Large NA NA


# Matrix B
[,1] [,2] [,3] [,4] [,5]
[1,] Z10 11 Nov 2012 Rocko Large Aldi CFO

在这种情况下,代码应在矩阵 A 的单元格 [1,9] 中插入“Aldi”,在单元格 [1,10] 中插入“CFO”,因为单元格 [1,1]、[1,2]、矩阵A中的[1,8]和[1,8]与矩阵B中的单元格[1,1]、[1,2]和[1,3]相同。

如果数据看起来像这样(第 2 列中的日期不同),代码不应该做任何事情;即,保留矩阵 A 中的单元格 [1,9] 和 [1,10]。

    # Matrix A
[,1] [,2] [,8] [,9] [,10]
[1,] Z10 15 Dec 2013 Rocko Large NA NA


# Matrix B
[,1] [,2] [,3] [,4] [,5]
[1,] Z10 11 Nov 2012 Rocko Large Aldi CFO

最佳答案

这是一种完全避免循环的方法,而是使用连接来达到相同的效果:

set.seed(1)

# Create some fake data with the given dimensions
matrix_a <- matrix(sample(letters, 14 * 250000, replace = T), ncol = 14)
matrix_b <- matrix(sample(letters, 5 * 23000, replace = T), ncol = 5)

library(dplyr)

# Convert matrices to data frames
df_a <- as_tibble(matrix_a)
df_b <- as_tibble(matrix_b)

# Simplify df_b so that multiple rows from df_b don't match the same row
# in df_a: this is implied by the loop in the question, and isn't necessary
# to do for the real data, if the condition holds.
df_b <- df_b %>%
distinct(V1, V2, V3, .keep_all = T)

new <- df_a %>%
# join columns from b to a that match on the specified variables
left_join(df_b %>% rename_all(~ paste0("b_", .)),
by = c(V1 = "b_V1", V2 = "b_V2", V8 = "b_V3")) %>%
# if there was a match in b, replace value in a with the value from b
mutate(
V9 = if_else(!is.na(b_V4), b_V4, V9),
V10 = if_else(!is.na(b_V5), b_V5, V10)
) %>%
# drop the added columns from b
select(-starts_with("b_"))

对于所花费的时间:在我的机器上加入和变异花费了 0.17 秒。

如果您想了解有关 dplyr 中可用的数据整理工具的更多信息,一个不错的起点是 package vignettewebsite .


检查应该改变的行,确实改变了:

should_change <- df_a %>% 
mutate(row_id = row_number()) %>%
semi_join(df_b, by = c("V1", "V2", V8 = "V3"))

new %>%
mutate(row_id = row_number()) %>%
select(row_id, V9, V10) %>%
inner_join(should_change %>% select(row_id, V9, V10),
by = "row_id", suffix = c("_new", "_old"))
#> # A tibble: 181,708 x 5
#> row_id V9_new V10_new V9_old V10_old
#> <int> <chr> <chr> <chr> <chr>
#> 1 1 j k p m
#> 2 3 n e f h
#> 3 4 s n v s
#> 4 6 m r j n
#> 5 7 c v t k
#> 6 8 m n u y
#> 7 9 m x l r
#> 8 10 e a z v
#> 9 11 e q l k
#> 10 12 o f z q
#> # ... with 181,698 more rows

关于r - 简化双for循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47012660/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com