0%

R语言-dplyr tricks

记录下dplyr包的一些有用的操作函数

行/列名转化

修改列名,常见的会用colnames()或者names(),对于搭配管道符%>%,可以用rename()

# rename(df, new_name = old_name) #For renaming dataframe column
mtcars %>%
  rename(mpg1 = mpg) %>%
  names()

如果想通过column index修改列名,比如修改第一列的列名:

mtcars %>%
  rename(mpg1 = 1) %>%
  names()

rename函数不仅可以修改指定单列的列名,多于多列也适用

mtcars %>%
  rename(mpg1 = mpg, cyl1 = cyl) %>%
  names()

如果想通过常规的colnames()函数来修改列名,但又想通过管道符%>%的形式,则:

mtcars[,1:2] %>%
  `colnames<-`(c("mpg1", "cyl1")) %>%
  names()

如果想修改d开头的列名为D开头,则可以用rename_at()函数,配合var函数来选择指定匹配的列

mtcars %>% 
  rename_at(vars(starts_with("d")), list(~str_replace(., "d", "D"))) %>%
  names()

此外还有rename_if(), rename_all(),用法跟上述类似

对于行/列相互转化问题,比如将行名转化成一列,则可rownames_to_column()或者rowid_to_column()函数

mtcars %>% 
  rownames_to_column(var = "rowname") %>%
  rowid_to_column(var = "rowid")

column_to_rownames()函数则是将某列转化为行名

mtcars %>% 
  rownames_to_column(var = "rowname") %>%
  rowid_to_column(var = "rowid") %>%
  column_to_rownames(var = "rowname")

常见的mutate()或者summarise()是对列进行统计运算的,如果想对行则可以使用rowwise()

mtcars %>%
  select(one_of("mpg", "cyl", "disp")) %>%
  rowwise() %>%
  mutate(avg = mean(c(mpg, cyl)))

Filter-过滤

使用filter()函数来过滤时,常见的是用运算符以及%in%等作为判定条件

mtcars %>% 
  filter(cyl == 6 & hp < 260)
  
mtcars %>% 
  filter(cyl %in% c(4, 6))

对于一些通过匹配的方式来过滤的,可以配合str_detect()函数来使用,如

mtcars %>% 
  rownames_to_column(var = "rowname") %>%
  filter(str_detect(rowname, "Merc"))

如果想过滤掉指定列中含有NA的行,或者所有含有NA的行,则:

mtcars$mpg[sample(32, 3)] <- NA
mtcars %>%
  filter(!is.na(mpg)) %>%
  nrow()

mtcars %>% 
  na.omit %>%
  nrow()

如果想用select()过滤未数字的列,可以使用~!is.numeric(.),这里的~代表function

msleep %>%
  select_if(~!is.numeric(.)) %>%
  glimpse

Summarise使用

如果想summarise特定的列,则可以用summarise_at()

mtcars %>% 
  group_by(cyl) %>% 
  summarise_at(c("mpg", "disp", "hp"), mean)

在上述基础上想对多列进行多个summarise函数,则:

mtcars %>% 
  group_by(cyl) %>% 
  summarise_at(c("mpg", "disp", "hp"), 
               c(Mean = "mean", SD = "sd"))

如果在summarise后想要只保留数值型(或者其他类型的数据),则可以用summarise_if()

mtcars %>% 
  group_by(cyl) %>% 
  summarise_if(is.numeric, mean) 

如果想在summarise内加入if等判断,则可以用function方式

mtcars %>% 
  group_by(cyl) %>% 
  summarise_if(function(x) is.numeric(x) & n_distinct(x) > 6, mean)

动态变量

dplyr包中mutate()函数使用动态变量(版本>=0.7),如:

# --- dplyr version 0.7+---
multipetal <- function(df, n) {
    varname <- paste("petal", n , sep=".")
    mutate(df, !!varname := Petal.Width * n)
}

filter()中想用动态变量进行过滤,则:

x <- "Protein_foldchange"
data2 <- filter(data, !!as.name(x) < 1)

如果是在ggplot2绘图中用动态变量(即将变量赋值为参数),可以用aes_string函数

x <- "Species"
ggplot(iris, aes_string(x = "Sepal.Length", y = "Sepal.Width", color = x)) +
  geom_point()

如果想在shiny中使用动态变量绘制ggplot2图,也可以利用rlang::sym转化string为symbol这种方法。。。

x <- rlang::sym(input$x)
y <- rlang::sym(input$y)
color <- rlang::sym(input$color)
ggplot(big_epa_cars, aes(!!x, !!y, color = !!color)) +
  geom_point()

如果将动态变量用于公式表达式,则可以参照:Formula with dynamic number of variables

factors <- c("factor1", "factor2")
as.formula(paste("y~", paste(factors, collapse="+")))

assign()循环给变量赋值

for (i in 1:3){
  assign(paste("a", i, sep = ""), i:10)
}

参考资料

https://sebastiansauer.github.io/dplyr_filter/
https://honingds.com/blog/dplyr-rename/
https://r.programmingpedia.net/en/tutorial/4250/dplyr
rlang 0.4.0

本文出自于http://www.bioinfo-scrounger.com转载请注明出处