2013-02-22 106 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