我正在運行一個帶有 for 回圈的查詢,該回圈創建不同長度的向量。第一個向量的代碼不一定是最長的(我創建了這個例子,所以第一列是最短的并且越來越長)。我想以某種方式系結這些向量。我弄亂了這個臨時 cbind.fill 函式,但沒有讓它作業(rowr::cbind.fill 在 R 4.xx 中不再可用)。
下面的示例代碼無法正常運行,因為runif(i)每個后續回圈都會使向量變長。請注意,對于實際資料,我不知道哪一列最長。檢查這是可能的但不是首選,盡管我可以想象可能只是保持向量直到回圈完成然后系結它們會更快。
示例代碼:
dat <- c(1,2,3)
dat <- as.data.frame(dat)
for (i in 1:5) {
temp <- runif(i)
dat <- cbind(dat, temp)
names(dat)[i 1] <- paste0("nr", i)
}
將輸出向量轉換為 data.frame的最快方法是什么?我想先將它們放入向量串列中(但在這種情況下不知道如何命名),或者可能用 NA 的數量填充每個向量length(longest_vector)-length(vector[i])。
期望的輸出:
# A tibble: 8 x 6
dat nr1 nr2 nr3 nr4 nr5
<chr> <chr> <chr> <chr> <chr> <dbl>
1 1 1 1 1 1 1
2 2 2 2 2 2 2
3 3 3 3 3 3 3
4 NA 0.43526783056537444 0.25560407791435225 0.91653997616714789 0.62635622073335406 0.888
5 NA NA 0.56979342124862575 0.43296269966267631 0.46423817219260977 0.522
6 NA NA NA 0.89399553062032511 0.34917334540558442 0.745
7 NA NA NA NA 0.4131315834365703 0.0403
8 NA NA NA NA NA 0.564
desired_out <- structure(list(dat = c("1", "2", "3", "NA", "NA", "NA", "NA",
"NA"), nr1 = c("1", "2", "3", "0.43526783056537444", "NA", "NA",
"NA", "NA"), nr2 = c("1", "2", "3", "0.25560407791435225", "0.56979342124862575",
"NA", "NA", "NA"), nr3 = c("1", "2", "3", "0.91653997616714789",
"0.43296269966267631", "0.89399553062032511", "NA", "NA"), nr4 = c("1",
"2", "3", "0.62635622073335406", "0.46423817219260977", "0.34917334540558442",
"0.4131315834365703", "NA"), nr5 = c(1, 2, 3, 0.887930290142606,
0.522131799371126, 0.745103223905874, 0.0403367661303002, 0.563609740553749
)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-8L))
uj5u.com熱心網友回復:
您可以使用plyr::ldply不同長度的多個向量
dat <- c(1,2,3)
dat <- as.data.frame(dat)
dat.list <- list(as.vector(t(dat)))
for (i in 1:5) {
dat.list[[(i 1)]] <- runif(i)
}
dat <- t(plyr::ldply(dat.list, rbind))
colnames(dat) <- c("dat", paste0("nr", 1:5))
> dat
dat nr1 nr2 nr3 nr4 nr5
1 1 0.8714848 0.8165862 0.5245153 0.7647691 0.15276644
2 2 NA 0.1034356 0.3850973 0.1769444 0.56437654
3 3 NA NA 0.3773377 0.9142521 0.31727519
4 NA NA NA NA 0.5343319 0.44647840
5 NA NA NA NA NA 0.07558151
使用檢查時間成本 microbenchmark::microbenchmark
microbenchmark::microbenchmark(
a = {dat <- c(1,2,3)
dat <- as.data.frame(dat)
dat.list <- list(as.vector(t(dat)))
for (i in 1:5) {
dat.list[[(i 1)]] <- runif(i)
}
dat <- t(plyr::ldply(dat.list, rbind))
colnames(dat) <- c("dat", paste0("nr", 1:5))}
)
Unit: milliseconds
expr min lq mean median uq max neval
a 5.008 5.3714 5.844143 5.6862 5.98705 9.84 100
對于 1000 -1000 長度的向量 -,
microbenchmark::microbenchmark(
a = {dat <- c(1,2,3)
dat <- as.data.frame(dat)
dat.list <- list(as.vector(t(dat)))
for (i in 1:1000) {
dat.list[[(i 1)]] <- runif(1000)
}
dat <- t(plyr::ldply(dat.list, rbind))
colnames(dat) <- c("dat", paste0("nr", 1:1000))}
)
Unit: milliseconds
expr min lq mean median uq max neval
a 127.9646 132.236 151.2108 135.2484 141.3047 369.3313 100
uj5u.com熱心網友回復:
所需輸出的前幾行看起來沒有添加資訊。
解決方案1
f <- function(vec, l){
nms <- paste0("nr", 1:l)
m1 <- matrix(vec, nrow = length(vec), ncol = l)
colnames(m1) <- nms
m <- matrix(, nrow = l, ncol = l)
for (i in seq_along(1:l)) {
m[1:i, i] <- runif(i)
}
colnames(m) <- nms
dplyr::bind_rows(tibble::as_tibble(m1), tibble::as_tibble(m))
}
f(c(1L,2L,3L), 5L)
# A tibble: 8 x 5
nr1 nr2 nr3 nr4 nr5
<dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
4 0.244 0.0891 0.881 0.749 0.332
5 NA 0.407 0.519 0.479 0.113
6 NA NA 0.633 0.561 0.593
7 NA NA NA 0.409 0.631
8 NA NA NA NA 0.992
可以通過將 for 回圈轉換為 C 并洗掉所需輸出的前幾行的添加來完成進一步優化。
解決方案2
f2 <- function(vec, l){
m <- matrix(, nrow = l, ncol = l)
m[upper.tri(m, diag = TRUE)] <- runif(n = l^2 - l*(l-1) / 2)
colnames(m) <- paste0("nr", 1:l)
as.data.frame(m)
}
請注意,所需的輸出具有字符向量作為輸出 - 這是有問題的記憶體管理。mutate(across(where(is.numeric), as.character))如果需要,可以使用。
基準
在函式的主力上執行基準測驗,創建一個 1000 x 1000 的 data.frame。
# rewriting f to not output first rows
f_clean <- function(vec, l){
m <- matrix(, nrow = l, ncol = l)
for (i in seq_along(1:l)) m[1:i, i] <- runif(i)
colnames(m) <- paste0("nr", 1:l)
as.data.frame(m)
}
bench::mark(f = {set.seed(1);f_clean(1L:1000L, 1000L)},
f2 = {set.seed(1); f2(1L:1000L, 1000L)}, iterations = 100)[c(3,5,7)]
median mem_alloc n_itr
<bch:tm> <bch:byt> <int>
1 22.4ms 31.3MB 94 #note: tibble output is slightly more memory(27MB) friendly
2 26ms 44MB 88
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/348097.html
下一篇:如何根據選定的數字顯示文本欄位?
