2013-02-22 95 views
1

問題解決了,解決方案添加在發佈的底部!在數據框中插入「空」行(填滿)R

我想知道如何通過在現有行之間插入行來填充數據框(而不是追加到最後)。

我的情況是以下幾點:

  • 我有一個數據集與約1700例,650個變量
  • 某些變量有可能的答案類別從0到100(的問題是:「百分之多少.. 。「 - >人們可以填寫從0到100)
  • 現在我想在geom_area()中顯示其中一個變量的分佈(我們稱之爲var)。

問題:

1)I需要X軸從0至100

2)未在變種被選擇所有可能的百分比值,例如我有30倍回答「20%」,但沒有回答「19%」。對於x軸,這意味着x位置19處的y值是「0」,x位置20處的y值是「30」。

要與ggplot繪製它準備我的數據(這個變量),我通過表函數transformend它:

dummy <- as.data.frame(table(var)) 

現在我有一欄「VAR1」的答覆類別和一列「 Freq「與每個答案類別的計數。

總的來說,我有57行,這意味着44個可能的答案(值從0到100%)沒有說明。

實例(我的數據框的),「VAR1」包含給定的答案,「頻率」的計數:

 Var1 Freq 
1  0 1 
2  1 16 
3  2 32 
4  3 44 
5  4 14 
... 
15 14 1 
16 15 169 # <-- See next row and look at "Var1" 
17 17 2 # <-- "16%" was never given as answer 

現在我的問題是:如何可以創建後插入一行新的數據幀第16行(「Var1」= 15),我可以設置「Var1」爲16,「Freq」爲0?

 Var1 Freq 
... 
15 14 1 
16 15 169 
17 16 0 # <-- This line I like to insert 
18 17 2 

我已經嘗試過這樣的事情:

dummy_x <- NULL 
dummy_y <- NULL 

for (k in 0:100) { 
    pos <- which(dummy$Var1==k) 
    if (!is.null(pos)) { 
    dummy_x <- rbind(dummy_x, c(k)) 
    dummy_y <- rbind(dummy_y, dummy$Freq[pos]) 
    } 
    else { 
    dummy_x <- rbind(dummy_x, c(k)) 
    dummy_y <- rbind(dummy_y, 0) 
    } 
} 

newdataframe <- data.frame(cbind(dummy_x), cbind(dummy_y)) 

這導致dummy_x有101個值誤差(從0到101,正確的),但dummy_y只包含56行?

結果應該繪製這樣的:提前

plot(ggplot(newdataframe, aes(x=Var1, y=Freq)) + 
    geom_area(fill=barcolors, alpha=0.3) + 
    geom_line() + 
    labs(title=fragetitel, x=NULL, y=NULL)) 

感謝, 丹尼爾

解決這個問題

plotFreq <- function(var, ftitle=NULL, fcolor="blue") { 
# create data frame from frequency table of var 
# to get answer categorie and counts in separate columns 
dummyf <- as.data.frame(table(var)) 
# rename to "x-axis" and "y-axis" 
names(dummyf) <- c("xa", "ya") 
# transform $xa from factor to numeric 
dummyf$xa <- as.numeric(as.character(dummyf$xa)) 
# get maximum x-value for graph 
maxval <- max(dummyf$xa) 
# Create a vector of zeros 
frq <- rep(0,maxval) 
# Replace the values in freq for those indices which equal dummyf$xa 
# by dummyf$ya so that remaining indices are ones which you 
# intended to insert 
frq[dummyf$xa] <- dummyf$ya 
# create new data frame 
newdf <- as.data.frame(cbind(var = 1:maxval, frq)) 
# print plot 
ggplot(newdf, aes(x=var, y=frq)) + 
    # fill area 
    geom_area(fill=fcolor, alpha=0.3) + 
    # outline 
    geom_line() + 
    # no additional labels on x- and y-axis 
    labs(title=ftitle, x=NULL, y=NULL) 
} 

回答

3

稱呼它,我認爲這是非常簡單的解決方案。循環不是必需的。想法是創建一個所需結果大小的向量,將所有值設置爲零,然後用頻率表中的非零值替換適當的值。

> #Let's create sample data 
> set.seed(12345) 
> var <- sample(100, replace=TRUE) 
> 
> 
> #Lets create frequency table 
> x <- as.data.frame(table(var)) 
> x$var <- as.numeric(as.character(x$var)) 
> head(x) 
    var Freq 
1 1 3 
2 2 1 
3 4 1 
4 5 2 
5 6 1 
6 7 2 
> #Create a vector of 0s 
> freq <- rep(0, 100) 
> #Replace the values in freq for those indices which equal x$var by x$Freq so that remaining 
> #indices are ones which you intended to insert 
> freq[x$var] <- x$Freq 
> head(freq) 
[1] 3 1 0 1 2 1 
> #cbind data together 
> freqdf <- as.data.frame(cbind(var = 1:100, freq)) 
> head(freqdf) 
    var freq 
1 1 3 
2 2 1 
3 3 0 
4 4 1 
5 5 2 
6 6 1 
+0

非常感謝,工作正常! :-) – Daniel 2013-02-22 11:00:01

+0

也許那麼你應該接受並upvote :) – 2013-02-22 11:00:37

+0

仍然必須習慣用戶/答案投票系統...... ;-) – Daniel 2013-02-22 11:12:42

2

嘗試這樣的事情

insertRowToDF<-function(X,index_after,vector_to_insert){ 
     stopifnot(length(vector_to_insert) == ncol(X)); # to check valid row to be inserted 
     X<-rbind(X[1:index_after,],vector_to_insert,X[(index_after+1):nrow(X),]); 
     row.names(X)<-1:nrow(X); 
     return (X); 
} 

你可以用

df<-insertRowToDF(df,16,c(16,0)); # inserting the values (16,0) after the 16th row 
+0

我不知道是否有解決方案中的一些打字錯誤?是「stopifnot(length(vector_to_insert!= ncol(X))」在行尾沒有關閉「)」?但是,如果我解決這個問題,我會收到錯誤消息「length(vector_to_insert!= ncol(X))不是TRUE」 – Daniel 2013-02-22 10:31:48

+0

是的,我只是將它輸入到瀏覽器中。它現在應該工作;我編輯過它。現在就試試!=應該是== – 2013-02-22 10:34:04

+0

這個解決方案也可以正常工作!非常感謝! – Daniel 2013-02-22 11:16:23

2

這是阿迪亞的代碼,加上一些條件,以處理特殊情況:

insertRowToDF<-function(X,index_after,vector_to_insert){ 
    stopifnot(length(vector_to_insert) == ncol(X)); # to check valid row to be inserted 
    if (index_after != 0) { 
    if (dim(X)[1] != index_after) { 
    X <- rbind(X[1:index_after,], vector_to_insert, X[(index_after+1):nrow(X),]); 
    } else { 
    X <- rbind(X[1:index_after,], vector_to_insert); 
    } 
    } else { 
    if (dim(X)[1] != index_after) { 
    X <- rbind(vector_to_insert, X[(1):nrow(X),]); 
    } else { 
    X <- rbind(vector_to_insert); 
    } 
    } 
    row.names(X)<-1:nrow(X); 
    return (X); 
}  
+1

感謝您的代碼。您的代碼啓用原始代碼無效的空'第一行'。 – Geoff 2015-12-02 15:46:15