R

时间:2015-05-25 00:04:02

标签: r ggplot2

我目前正在尝试创建一个函数来格式化我的数据并正确地返回一个已排序的条形图。但由于某些原因,我一直收到这个错误:

 Error in `$<-.data.frame`(`*tmp*`, "Var1", value = integer(0)) : 
  replacement has 0 rows, data has 3 

我试过调试它,但没有运气。我有一个例子,我期望在底部。谁能发现我做错了什么?

x <- rep(c("Mark","Jimmy","Jones","Jones","Jones","Jimmy"),2)
y <- rnorm(12)
df <- data.frame(x,y)


plottingfunction <- function(data, name,xlabel,ylabel,header){
  newDf <- data.frame(table(data))
  order <- newDf[order(newDf$Freq, decreasing = FALSE), ]$Var1
  newDf$Var1 <- factor(newDf$Var1,order)
  colnames(newDf)[1] <- name

  plot <- ggplot(newDf, aes(x=name, y=Freq)) +
                xlab(xlabel) +
                ylab(ylabel) +
                ggtitle(header) +
                geom_bar(stat="identity", fill="lightblue", colour="black") +
                coord_flip()
  return(plot)

}

plottingfunction(df$x, "names","xlabel","ylabel","header")

enter image description here

1 个答案:

答案 0 :(得分:2)

一些评论,你的功能没有用,因为这部分不正确:

order <- newDf[order(newDf$Freq, decreasing = FALSE), ]$Var1

由于我们不知道data中是否有任何列名为Var1的列。看起来像是在你尝试运行你的代码的时候:

newDf <- data.frame(table(df$x))

立即将您的列重命名为Var1,但是当您运行您的函数时,名称已更改。因此,为了解决这个问题,我建议您明确使用列名。在这个例子中,我使用dplyr库让我的生活更轻松。因此,遵循您的代码和逻辑,它将如下所示:

newDf <- data %>% group_by_(col_name) %>% tally
order <- newDf[order(newDf$n, decreasing = FALSE), col_name][[col_name]]
data[,col_name] <- factor(data[,col_name], order)

然后在ggplot内我们可以使用aes_string来引用数据框的列名。那么整个函数看起来像这样:

plottingFunction <- function(data, col_name, xlabel, ylabel, header) {
  #' create a dataframe with the data that we're interested in 
  #' make sure that you preserve the anme of the column that you're
  #' counting on...
    newDf <- data %>% group_by_(col_name) %>% tally
    order <- newDf[order(newDf$n, decreasing = FALSE), col_name][[col_name]]
    data[,col_name] <- factor(data[,col_name], order)

  plot <- ggplot(data, aes_string(col_name)) +
    xlab(xlabel) +
    ylab(ylabel) +
    ggtitle(header) +
    geom_bar(fill="lightblue", colour="black") +
    coord_flip()
  return(plot)
}

plottingFunction(df, "x", "xlabel","ylabel","header")

哪个输出会像:

enter image description here

我认为你的情节stat="identity"是多余的,因为你可以使用你的原始数据框而不是改变它。