问题解决了,在帖子底部添加了解决方案!
我想知道如何通过在现有行之间插入行来“填充”数据框(不附加到结尾)。
我的情况如下:
问题:
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))
提前致谢, 丹尼尔
解决此问题的方法
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)
}
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分:2)
这是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);
}