在 R 的数据框中插入"empty"行(填充)



问题已解决,解决方案已添加到过帐底部

我想知道如何通过在现有行之间插入行(而不是追加到末尾)来"填充"数据帧。

我的情况如下:

  • 我有一个包含大约1700个病例和650个变量的数据集
  • 某些变量的答案类别可能从0到100(问题是:"有多少百分比…"->人们可以从0到100%填写)
  • 现在,我想显示其中一个变量(让我们称之为var)在geom_area()中的分布

问题:

1) 我需要一个从0到100 的X轴

2) 并非所有var中可能的百分比值都被选中,例如,我有30倍的答案"20%",但没有答案"19%"。对于x轴,这意味着x位置19处的y值为"0",x位置20处的y值为"30"。

为了准备我的数据(这个变量)用ggplot绘制它,我通过表函数转换它:

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

现在我有一列"Var1"和一列"Freq",分别列出了答案类别和每个答案类别的计数。

总共,我有57行,这意味着没有说明44个可能的答案(值从0到100%)。

示例(我的数据帧),"Var1"包含给定的答案,"Freq"计数:

     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))

提前感谢,Daniel

此问题的解决方案

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)
}

我认为这是一个简单得多的解决方案。循环不是必须的。想法是创建一个所需结果大小的向量,将所有值设置为零,然后用频率表中的非零值替换适当的值。

> #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

尝试类似的东西

 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

这是Aditya的代码加上一些处理特殊情况的条件:

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);
 }     

最新更新