我正在尝试将整数(“ i”)传递给其中将“ i”用作数据帧的行索引的函数。但是,这样做...
user_definedFUN <- function (i){
...
result <- df[i, "col_name"]
...
}
x <- user_definedFUN(1)
...产生以下错误:
Error in `[.data.frame`(df, i, "col_name") :
object 'i' not found
我确定这是一个简单的问题,即如何在方括号内引用“ i”(即使不够简单,我无法找到解决方案);但是,如有必要,我在下面提供了其他详细信息。
data.frame:
gen_name <- c("Boomers","Gen X","Millenials","Gen Z")
gen_years <- c("1946 to 1964","1965 to 1980","1981 to 1996", "1997 to 2011")
gen_xmin <- c(11, 9, 5, 2)
gen_xmax <- c(15, 11, 8, 5)
GEN_G.labels <- data.frame(gen_name, gen_years, gen_xmin, gen_xmax)
data.frame包含四代的信息,这些信息将用于按年龄绘制ggplot人口图上的矩形作为图层。
矩形将通过以下函数创建,该函数将从循环中调用,并提供特定生成的行索引(1 =“ Boomers”,2 =“ Gen X”等)
genlabelsFUN <- function(i){
# return a geom_rect()
rv <- geom_rect(aes(
xmin = GEN_G.labels[i, "gen_xmin"],
xmax = GEN_G.labels[i, "gen_xmax"],
ymin = 1000,
ymax = 1100)
, fill = "red")
return(rv)
}
ggplot(...snip...) +
...snip... +
genlabelsFUN(1)
如果使用静态索引值,该函数将起作用。例如,用'GEN_G.labels [ 1 ,“ gen_xmin”]'代替'GEN_G.labels [ i ,“ gen_xmin”]'在11和在x轴上为15,在y轴上为1,000,高度为100。尽管如此,如果没有“ i”的动态方面,该函数将毫无意义。
下图显示了使用静态索引值时的输出(注意:为简单起见,我在上面的示例中使用了不同的y轴刻度)。最终代码将遍历GEN_G.labels的每一行,并运行genlabelsFUN()为每一代创建一个相似的矩形。
谢谢
编辑:
完整ggplot
scaleFUN <- function(x) formatC( x / 1000, format = "f", big.mark = ",", digits = 0) #format as thousands with comma
ggplot(data = GEN_G.data_frame, aes(x = range, y = persons)) +
geom_bar(stat = "identity") +
theme_classic() +
theme(
axis.text.x = element_text(angle = 90, hjust = 1)) +
scale_y_continuous(
name = "Persons (thousands)",
labels = scaleFUN) +
genlabelsFUN(1)
编辑2:
可复制的示例(基于下面的MrFlick注释起作用)
GEN_G.dataframe <- data.frame(
range = c(1:21),
persons = abs(rnorm(21))*50)
GEN_G.labelsx <- data.frame(
gen_name = c("Group A","Group B","Group C","Group D"),
gen_xmin = c(11, 9, 5, 2),
gen_xmax = c(15, 11, 9, 5))
GEN_G.labelsx$gen_name <- factor(
GEN_G.labelsx$gen_name,
levels = GEN_G.labelsx$gen_name)
ggplot() +
geom_bar(data=GEN_G.dataframe,aes(x=range, y=persons),stat="identity") +
theme_classic() +
theme(
axis.text.x = element_text(angle = 90, hjust = 1)) +
geom_rect(aes(
xmin = gen_xmin,
xmax = gen_xmax,
ymin = 175,
ymax = 180,
fill = gen_name),
data = GEN_G.labelsx)
“编辑2”示例的输出。
答案 0 :(得分:0)
您不能在i
中使用像aes()
这样的变量。在aes()
内的符号不会被评估,直到实际绘制绘图为止。如果以这种方式定义i
,那么R就无法正确捕获环境,因此在绘制图形时该值将已更改。
但是,我什至不认为循环/函数甚至不是必需的。您应该能够做到
geom_rect(aes(xmin=gen_xmin, xmax=gen_xmax), ymin=1000, ymax=1000, data=GEN_G.labels)
对该层使用不同的data.frame。然后立即绘制所有框,而无需循环。