当我不知道data.frame中的列名时,当我使用dplyr mutate函数时

时间:2018-09-04 19:28:55

标签: r dplyr

我想知道当我不知道列名时如何使用dplyr mutate函数。这是我的示例代码;

library(dplyr)
w<-c(2,3,4)
x<-c(1,2,7)
y<-c(1,5,4)
z<-c(3,2,6)
df <- data.frame(w,x,y,z)
df %>% rowwise() %>% mutate(minimum = min(x,y,z))

Source: local data frame [3 x 5]
Groups: <by row>

# A tibble: 3 x 5
      w     x     y     z     minimum
    <dbl> <dbl> <dbl> <dbl>   <dbl>
1     2     1     1     3       1 
2     3     2     5     2       2 
3     4     7     4     6       4

此代码按行查找最小值。是的,“ df%>%rowwise()%>%mutate(minimum = min(x,y,z))”之所以有效,是因为我键入了列名x,y,z。但是,让我们假设我有一个非常大的data.frame,其中有几百列,而我并不知道所有的列名。或者,我有多个data.frame数据集,并且它们都有所有不同的列名;我只想在每行和每个data.frame中找到从第10列到第20列的最小值。

在上面提供的这个示例data.frame中,让我们假设我不知道列名,但是我只想获取每行第二列到第四列的最小值。当然,这是行不通的,因为'mutate'对vector无效。

df %>% rowwise() %>% mutate(minimum=min(df[,2],df[,3], df[,4]))  

Source: local data frame [3 x 5]
Groups: <by row>

# A tibble: 3 x 5
       w     x     y     z    minimum
     <dbl> <dbl> <dbl> <dbl>   <dbl>
 1     2     1     1     3       1
 2     3     2     5     2       1
 3     4     7     4     6       1

下面的这两个代码也不起作用。

 df %>% rowwise() %>% mutate(average=min(colnames(df)[2], colnames(df)[3], colnames(df)[4]))  
 df %>% rowwise() %>% mutate(average=min(noquote(colnames(df)[2]), noquote(colnames(df)[3]), noquote(colnames(df)[4])))  

我知道当我不知道列名时可以通过套用或其他方法获得最小值。但是,我想知道dplyr mutate函数是否可以在没有已知列名的情况下做到这一点。

谢谢

3 个答案:

答案 0 :(得分:2)

使用apply

library(dplyr)
library(purrr)

df %>%
  mutate(minimum = apply(df[,2:4], 1, min))

或使用pmap

df %>%
  mutate(minimum = pmap(.[2:4], min))

还有by_row中的purrrlyr

df %>%
  purrrlyr::by_row(~min(.[2:4]), .collate = "rows", .to = "minimum")

输出:

# tibble [3 x 5]
      w     x     y     z minimum
  <dbl> <dbl> <dbl> <dbl>   <dbl>
1     2     1     1     3       1
2     3     2     5     2       2
3     4     7     4     6       4

答案 1 :(得分:1)

向量化选项为pmin。用syms将列名转换为符号并求值(!!!)以返回应用了pmin的列的值

library(dplyr)
df %>% 
  mutate(minimum = pmin(!!! rlang::syms(names(.)[2:4])))
#  w x y z minimum
#1 2 1 1 3       1
#2 3 2 5 2       2
#3 4 7 4 6       4

答案 2 :(得分:0)

这是根据aosmith的建议的一种tidyeval方法。如果您不知道列名,则可以创建一个函数,该函数接受所需的位置作为输入并查找列名本身。在这里,rlang::syms()将列名作为字符串并将其转换为符号,!!!取消引号并将这些符号拼接到函数中。

library(dplyr)
w<-c(2,3,4)
x<-c(1,2,7)
y<-c(1,5,4)
z<-c(3,2,6)
df <- data.frame(w,x,y,z)

rowwise_min <- function(df, min_cols){
  cols <- df[, min_cols] %>% colnames %>% rlang::syms()
  df %>%
    rowwise %>%
    mutate(minimum = min(!!!cols))
}

rowwise_min(df, 2:4)
#> Source: local data frame [3 x 5]
#> Groups: <by row>
#> 
#> # A tibble: 3 x 5
#>       w     x     y     z minimum
#>   <dbl> <dbl> <dbl> <dbl>   <dbl>
#> 1     2     1     1     3       1
#> 2     3     2     5     2       2
#> 3     4     7     4     6       4
rowwise_min(df, c(1, 3))
#> Source: local data frame [3 x 5]
#> Groups: <by row>
#> 
#> # A tibble: 3 x 5
#>       w     x     y     z minimum
#>   <dbl> <dbl> <dbl> <dbl>   <dbl>
#> 1     2     1     1     3       1
#> 2     3     2     5     2       3
#> 3     4     7     4     6       4

reprex package(v0.2.0)于2018-09-04创建。