簡體   English   中英

在我使用來自原始數據集的信息創建新數據集時,如何簡化此代碼 (r)?

[英]How can I simplify this code (r) in which I am using information from an original data set to create a new dataset?

我有一個數據集,我試圖用它在 R 中生成不同的數據集。 數據集有很多列; 但生成新數據集的三個相關列是“Reach”、“Results”和“DV”。 范圍和結果是數字。 DV 是二進制的 0 和 1。 在原始數據集中,所有行的 DV = 0。

對於原始數據集的每一行,我試圖取一個變量“Reach”並復制該行“reach”次數。 然后對於這組新行,我想將新行的“結果”數(來自原始行)的 DV 從 0 更改為 1。

例如,在原始數據集的第 33 行:Reach = 1004,Results = 45,DV = 0。新數據集的第 33 行應復制 1004 次,其中 45 行 DV 應從 0 更改為 1 .

我為該任務編寫的代碼有效……但由於文件太大,需要 10 多個小時才能運行。 有關如何簡化此代碼以便更快處理的任何想法

empty_new.video <- new.video[FALSE,]
for(i in 1:nrow(new.video)){
  n.times <- new.video[i,'Reach'] #determine number of times to repeat rows
  if (n.times > 0){
    for (j in 1:n.times){
      empty_new.video[nrow(empty_new.video) + 1 , ] <- new.video[i,]
    }
  }
  dv.times <- new.video[i,'Results'] #creating dependent variable 
  if (dv.times>0){
    for (k in 1:dv.times){
      empty_new.video[nrow(empty_new.video) - n.times + k,'DV'] <- 1
    }
  }
}

避免在循環中增長對象。 考慮Map (包裝器到mapply )逐元素迭代所有原始數據集的列,以構建數據幀列表,最終在最后連接一次

build_rows <- function(reach, results) {
    # DATA FRAME TO REPLICATE REACH BY ITS LENGTH
    df <- data.frame(id = reach, reach = 1:reach, dv = 0)

    # RANDOMLY ASSIGN N ROWS TO 1 (N=RESULTS)  
    df$dv[sample(1:nrow(df), results),] = 1 

    # ASSIGN FIRST N ROWS TO 1 (N=RESULTS)
    df$dv[1:results,] = 1 

    return(df)
}

df_list <- Map(build_rows, original_data$Reach, original_data$Results)

final_df <- do.call(rbind, df_list)

您可以定義一個簡單的 function 而不是一個循環來一次完成所有操作,然后對一行執行此操作並檢查結果

dd <- data.frame(Reach = c(5, 3), Results = c(4, 1), DV = c(0, 0))
#   Reach Results DV
# 1     5       4  0
# 2     3       1  0

f <- function(data) {
  nr <- data$Reach
  nd <- data$Results
  data <- data[rep_len(1L, nr), ]
  data$DV <- rep(0:1, c(nr - nd, nd))
  rownames(data) <- NULL
  data
}
f(dd[1, ])

然后循環每一行

res <- lapply(split(dd, rownames(dd)), f)
do.call('rbind', res)
#     Reach Results DV
# 1.1     5       4  0
# 1.2     5       4  1
# 1.3     5       4  1
# 1.4     5       4  1
# 1.5     5       4  1
# 2.1     3       1  0
# 2.2     3       1  0
# 2.3     3       1  1

但實際上您所做的只是為DV創建行索引和 0/1 值的向量,您可以使用rep

ii <- rep(1:nrow(dd), dd$Reach)

jj <- c(t(cbind(dd$Reach - dd$Results, dd$Results)))
dv <- rep(rep(0:1, nrow(dd)), jj)

within(dd[ii, ], {
  DV <- dv
})
#     Reach Results DV
# 1       5       4  0
# 1.1     5       4  1
# 1.2     5       4  1
# 1.3     5       4  1
# 1.4     5       4  1
# 2       3       1  0
# 2.1     3       1  0
# 2.2     3       1  1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM