2016-05-09 72 views
-2

我正在處理bigdata數據框。 第一列包含字符串值,第二列包含數字數據。但是在第二個描述的塊中有一些NA不能刪除整行或列,因爲weill甚至會刪除重要數據 I想要創建一個包含相同第一列的新矩陣,但我需要新的數值數據,計算爲每行與包含所有數值總和的新行之間的比率;這是我做過什麼:彙總數據時出錯

df1<- df[,-(1)] 
tot<- colSums(df1, na.rm = TRUE) 
ratio <- df1/rep(tot, each = nrow(df1)) 
firstcol <- df[1] 
data <- cbind(firstcol ,ratio) 

在此之後,我想第一列聚合所有的值:

agg<- aggregate(. ~ firstColName, data, sum) 

但是這樣造成了我一個錯誤:

Error in aggregate.data.frame(lhs, mf[-1L], FUN = FUN, ...) : no rows to aggregate 

我試圖做出相同的聚合,排除這部分代碼:

ratio <- data/rep(tot, each = nrow(df1)) 

有作爲的結果:

df1<- df[,-(1)]  
firstcol <- df[1] 
data <- cbind(firstcol ,df1) 
agg<- aggregate(. ~ firstColName, data, sum) 

而且在這種情況下,它完美地工作,所以我認爲,原因僅僅是使用配方比例的。 我應該使用另一種方式來進行該操作嗎?

+0

@ZheyuanLi,我創建了一個新問題。 –

+0

@ZheyuanLi在之前的示例firstColName中是VAL1,但在那種情況下一切正常。只是使用我真正的df這是一個大數據,它沒有工作..我的意思是,聚合前的輸出是正確的,但聚合給我那個錯誤 –

+0

@ZheyuanLi,我試過了,但它給了我同樣的錯誤,奇怪的東西是,如果我添加一個新的行到'數據'具有相同的結構的所有以前的,它使得聚合,但最終的數據幀只包含新行 –

回答

2

真的很難猜測發生了什麼,而實際上並沒有看到你運行你的R代碼。由於您沒有顯示出對變量名稱的良好管理,因此您可能在實驗過程中屏蔽了變量。

我們浪費了大量的時間來猜測發生了什麼。我建議,我們嘗試了健壯的代碼版本。在下面,我提供給你一個函數,把你的數據框架作爲唯一的參數。 函數內部的變量不會與外部的變量衝突,即使它們具有相同的名稱

foo <- function (df) { 
    error.default <- getOption("error") 
    options(error = utils::recover) 
    n <- nrow(df) 
    value_df <- df[, -1] ## data frame with values 
    tot <- colSums(value_df, na.rm = TRUE) ## column sums 
    if (any(is.na(tot))) stop("NA detected in column sums! Exit!") 
    ratio <- value_df/rep(tot, each = n) ## rescaling 
    string_df <- df[1] 
    if (nrow(string_df) != nrow(ratio)) stop("dimension dismatch!!") 
    cat("\n") 
    data <- cbind(string_df ,ratio) 
    cat("data summary:\n") 
    cat(paste("number of rows: ", n, "\n",sep = "")) 
    cat(paste("number of columns: ", ncol(data), "\n",sep = "")) 
    ## NA summary: critical because aggregate will drop NA rows 
    ## when all rows are dropped, aggregate complains "no row to aggregate" 
    data <- na.omit(data) 
    cat(paste("The number of non-NA rows passed to aggregate:", nrow(data))); cat("\n") 
    cat("\n") 
    if (nrow(data) == 0) stop("All rows are dropped! Exit!!") 
    formula <- as.formula(paste(". ~", colnames(df)[1])) 
    cat("the formula is: ") 
    print(formula); cat("\n") 
    agg <- aggregate(formula, data, FUN = sum) 
    cat("aggregation success!!\n\n") 
    options(error = error.default) 
    return(agg) 
    } 

agg <- foo(df) 

如果出現任何錯誤,請將錯誤消息打印給我。


錯誤檢測

基於從上述功能的報告,當應用到你的完整的數據,我能收回你的情況下,有以下簡單的例子。

以前,你給測試數據幀是:

VAL1 <- c("AA", "BB", "CC", "DD", "BB", "DD", "AA", "DD") 
Num1 <- c(1, 2, 1, 3, 4, 4, 6, 2) 
Num2 <- c(3, 3, 2, 1, 1, 2,4, 4) 
Num3 <- c(2, 2, 3, 4, 3, 5, 5, 7) 
df <- data.frame(VAL1, Num1, Num2, Num3) 

當你總該可以正常工作。現在讓我們試試這樣的:

VAL1 <- c("AA", "BB", "CC", "DD", "BB", "DD", "AA", "DD") 
Num1 <- c(NA, NA, 1, 3, 4, 4, 6, 2) 
Num2 <- c(3, 3, NA, NA, NA, 2,4, 4) 
Num3 <- c(2, 2, 3, 4, 3, NA, NA, NA) 
df <- data.frame(VAL1, Num1, Num2, Num3) 

那麼,你會得到什麼?您的完整數據集究竟發生了什麼。雖然每個單獨的列對於所有條目都沒有NA,但它們一起標記所有行以具有NAAggregate將會丟棄包含至少一個的任何行NA。這是aggregate的默認選項,有關參數na.action的參見?aggregate


你能做什麼?

既然你不想丟掉所有的NA,那麼你需要用一些合理的數值來代替它。在我看來,將所有NA設置爲0在你的問題中是合理的。當您使用tot<- colSums(df1, na.rm = TRUE)時,這相當於首先將所有NA設置爲0,然後應用正常版本tot<- colSums(df1)

如果您同意,我們可以這樣做:

df[is.na(df)] <- 0 ## set all NA to 0 

foo <- function (df) { 
    n <- nrow(df) 
    value_df <- df[, -1] ## data frame with values 
    tot <- colSums(value_df) ## column sums 
    ratio <- value_df/rep(tot, each = n) ## rescaling 
    string_df <- df[1] 
    data <- cbind(string_df ,ratio) 
    formula <- as.formula(paste(". ~", colnames(df)[1])) 
    aggregate(formula, data, FUN = sum) 
    } 

agg <- foo(df) ## use `NA` corrected df to aggregate 

這應該工作。

+0

我錯了,它只是因爲在第六行寫道: tot < - colSums(df1,na.rm = TRUE)##列總和,使用df1它把df我之前創建的樣本(在另一個問題中寫的樣本),所以他創建了分區。使用value_df更改df1會給我相同的舊錯誤:'foo(df)中的錯誤: 所有行都被刪除!退出!!' –

+0

你是對的,它會返回我真正的df的錯誤 –

+0

有沒有一種方法可以按名稱對它們進行分組並總結數值? –