如何制作创建自定义饼图的功能? (输入参数的问题)

How to make a function to create a customised pie chart? (problems in inputing the argument)

我是 R 的新手(到目前为止编码差不多一周)。对于这个简单的问题,我深表歉意。我正在尝试编写一个简单的函数,它将根据我要输入的数据集的变量创建一个饼图。

数据集是

ID<-c("001","002","003","004","005","006","007","008","009","010","NA","012","013")
Name<-c("Damon Bell","Royce Sellers",NA,"Cali Wall","Alan Marshall","Amari Santos","Evelyn Frye","Kierra Osborne","Mohammed Jenkins","Kara Beltran","Davon Harmon","Kaitlin Hammond","Jovany Newman")
Sex<-c("Male","Male","Male",NA,"Male","Male",NA,"Female","Male","Female","Male","Female","Male")
Age<-c(33,27,29,26,27,35,29,32,NA,25,34,29,26)
data1<-data.frame(ID,Name,Sex,Age)

没有该功能的代码是:

#calculation of counts
dSex <- data %>%
  filter(!is.na(Sex)) %>%
  group_by(Sex) %>% 
  summarise(Count = n()) %>%
  mutate(Total = sum(Count), Percentage = round((Count/Total),3))

## Compute the position of labels
dSex <- dSex %>% 
  arrange(desc(Sex)) %>%
  mutate(ypos = cumsum(Percentage)-0.5*Percentage)

dSex %>% 
  ggplot(aes(x="", y=Percentage, fill=Sex)) +
  geom_bar(stat="identity", color="White") +
  coord_polar("y", start=0) +
  geom_text(aes(y = ypos, label = paste0(round(Percentage*100,0),"%\n(", Count, ")")), color = "white") + 
  scale_fill_manual(values = c("#7e0f7e", "#026b6c")) +
  guides(fill = guide_legend(title = "Sex")) +
  theme(
    axis.title = element_blank(), 
    axis.line = element_blank(), 
    axis.text = element_blank() 
  ) 

所以我开始写函数,我已经很吃力了。我想以我称之为“dSex”的新数据的名称输入变量 Sex,但我认为它不起作用。我把 deparse() 和 substitute() 这行放在一起,因为我的理解是它有助于 R 理解“Var”是函数的参数。而且我还放了双“{”“}”但是它好像不读!

FctPieChart <- function(dat,Var){
  
  Var <- deparse(substitute({{Var}}))
  
  dVar <- dat %>%
    filter(!is.na({{Var}})) %>%
    group_by(Var) %>% 
    summarise(Count = n()) %>%
    mutate(Total = sum(Count), Percentage = round((Count/Total),3))
}  
FctPieChart(data,Sex)

我收到以下错误:

Error: Problem with `filter()` input `..1`.
i Input `..1` is `!is.na(c("{", " {", " Sex", " }", "}"))`.
x Input `..1` must be of size 13 or 1, not size 5.
Run `rlang::last_error()` to see where the error occurred.

你知道怎么做吗?

还有一个问题,我画的饼图很大,有没有办法缩小?

在此先感谢您,如果有人有任何想法,这对我真的很有帮助!

此致,

斯蒂芬妮

根据以下建议回答: 答案是在字符中输入变量(此处:Sex)作为函数的参数,并在我调用函数中的变量时使用函数 get()。 get() 将允许我将字符转换为变量。但是,函数 get() 的使用导致变量名称发生变化:“ get(Var) ”。我通过重命名数据中的变量并将第一个变量 Var 的副本创建为 Var2.

解决了这个问题

我还想获取在函数中停止创建的实际数据(它是在不在函数中的代码中创建的)。我发现 dVar <<- dVar 可以解决问题,因为它会创建数据。数据将被称为 dVar 并且名称不依赖于输入的变量(在旧代码中它是 dSex

因为我希望 table 的名称能够反映所使用的变量(而不是常规的“dVar”),我通过使用函数 assign() 和envir=.

更正后的代码如下:

FctPieChart <- function(dat,Var){

#Create a replacement of  `get(Var)`  to use later
Var2 <-Var #We will use this one later instead of Var since Var is going to be changed into something else
print(Var2)

#Frequencies table
dVar <- dat %>%
filter(!is.na(get(Var))) %>%
group_by(get(Var)) %>% #changes the name of the column to "`get(Var)`"
summarise(Count = n()) %>%
mutate(Total = sum(Count), Percentage = round((Count/Total),3))

#Position calculation for the Pie Chart
dVar <- dVar %>%
arrange(desc(`get(Var)`)) %>%
mutate(ypos = cumsum(Percentage)-0.5*Percentage)   print(dVar)

#Rename the variable that was changed in the data 
colnames(dVar)<-c(Var2,"Count","Total","Percentage","ypos") 
print(dVar)

#Make the graph
Graph <- dVar %>% 
ggplot(aes(x="", y=Percentage, fill=get(Var2))) +#fill=`get(Var)`)  #get(Var2) alloWs to transform character into variable
geom_bar(stat="identity", color="White") +
coord_polar("y", start=0) +
geom_text(aes(y = ypos, label = paste0(round(Percentage*100,0),"%\n(", Count, ")")), color = "white") + 
scale_fill_manual(values = c("#7e0f7e", "#026b6c")) +
guides(fill = guide_legend(title = Var2)) + #title = Var2 takes the value as characters of Var2 
theme(
axis.title = element_blank(), 
axis.line = element_blank(), 
axis.text = element_blank() 
)
print(Graph)

#Create the table
dVar<<-dVar

#Change name of the data based on the variable 
assign(paste0("d",Var2),dVar,envir = parent.frame()) #use envir = parent.frame() to access the environment outside the function, source: 
rm(dVar,envir = parent.frame())
}
FctPieChart(data,"Sex")

感谢@Silentdevildoll 帮我解决了问题

祝你有美好的一天!

斯蒂芬妮

我以前从来没有用过这样的东西,我的代码肯定有缺陷,但这是我试图帮助你的尝试。我相信其他人会有更好的解决方案,但这至少是一个开始:

FctPieChart <- function(dat,Var){
  
  dVar <- dat %>%
    filter(!is.na(get(Var))) %>%
    group_by(get(Var)) %>%
    summarise(Count = n()) %>%
    mutate(Total = sum(Count), Percentage = round((Count/Total),3))
  
  dVar <- dVar %>%
    arrange(desc(`get(Var)`)) %>%
    mutate(ypos = cumsum(Percentage)-0.5*Percentage)
  print(dVar)
  dVar %>% 
    ggplot(aes(x="", y=Percentage, fill=`get(Var)`)) +
    geom_bar(stat="identity", color="White") +
    coord_polar("y", start=0) +
    geom_text(aes(y = ypos, label = paste0(round(Percentage*100,0),"%\n(", Count, ")")), color = "white") + 
    scale_fill_manual(values = c("#7e0f7e", "#026b6c")) +
    guides(fill = guide_legend(title = "Sex")) +
    theme(
      axis.title = element_blank(), 
      axis.line = element_blank(), 
      axis.text = element_blank() 
    ) 
  
}  
FctPieChart(data1,"Sex")

我不太熟悉你使用的 deparse(substitute),但我知道 get() 是一种将字符串转换为变量的方法,所以基本上我替换了第一段中的 Var get(Var) 的函数。然而,我确定这并不理想,因为 group_by(get(Var)) 将列的名称更改为 get(Var),我通过打印 table 来演示了这一点。请注意,我还将变量输入为“Sex”,而不仅仅是 Sex。正如我所说,这并不完美,但我认为这可能会为您指明正确的方向。