dplyr rowwise sum和其他函数,如max

mja*_*ews 4 r dplyr rowwise

如果我想在数据框中使用一些变量求和dplyr,我可以这样做:

> head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

> select(iris, starts_with('Petal')) %>% rowSums()
  [1] 1.6 1.6 1.5 1.7 1.6 2.1 1.7 1.7 1.6 1.6 1.7 1.8 1.5 1.2 1.4 1.9 1.7 1.7 2.0 1.8 1.9 1.9 1.2 2.2 2.1 1.8 2.0 1.7 1.6 1.8 1.8 1.9 1.6 1.6 1.7 1.4
 [37] 1.5 1.5 1.5 1.7 1.6 1.6 1.5 2.2 2.3 1.7 1.8 1.6 1.7 1.6 6.1 6.0 6.4 5.3 6.1 5.8 6.3 4.3 5.9 5.3 4.5 5.7 5.0 6.1 4.9 5.8 6.0 5.1 6.0 5.0 6.6 5.3
 [73] 6.4 5.9 5.6 5.8 6.2 6.7 6.0 4.5 4.9 4.7 5.1 6.7 6.0 6.1 6.2 5.7 5.4 5.3 5.6 6.0 5.2 4.3 5.5 5.4 5.5 5.6 4.1 5.4 8.5 7.0 8.0 7.4 8.0 8.7 6.2 8.1
[109] 7.6 8.6 7.1 7.2 7.6 7.0 7.5 7.6 7.3 8.9 9.2 6.5 8.0 6.9 8.7 6.7 7.8 7.8 6.6 6.7 7.7 7.4 8.0 8.4 7.8 6.6 7.0 8.4 8.0 7.3 6.6 7.5 8.0 7.4 7.0 8.2
[145] 8.2 7.5 6.9 7.2 7.7 6.9
Run Code Online (Sandbox Code Playgroud)

那没关系,但我原本以为会rowwise完成同样的事情,但事实并非如此,

> select(iris, starts_with('Petal')) %>% rowwise() %>% sum()
[1] 743.6
Run Code Online (Sandbox Code Playgroud)

我特别想要做的是选择一组列,并创建一个新变量,其中每个值都是所选列的每一行的最大值.例如,如果我选择"Petal"列,则最大值将为1.4,1.4,1.3等.

我可以这样做:

> select(iris, starts_with('Petal')) %>% apply(1, max)
Run Code Online (Sandbox Code Playgroud)

那没关系.但我只是好奇为什么这种rowwise方法不起作用.我意识到我使用rowwise不正确,我只是不确定为什么它是错的.

G. *_*eck 8

问题是尽管如此,整个数据框仍以点的形式传递rowwise.处理这种用法do,将dot解释为仅表示当前行.另一个问题是内部的do点将行表示为列表,因此适当地进行转换.

iris %>%
  slice(1:6) %>%
  select(starts_with('Petal')) %>% 
  rowwise() %>%
  do( (.) %>% as.data.frame %>% mutate(sum = sum(.)) ) %>%
  ungroup
Run Code Online (Sandbox Code Playgroud)

赠送:

# A tibble: 6 x 3
  Petal.Length Petal.Width   sum
*        <dbl>       <dbl> <dbl>
1         1.40       0.200  1.60
2         1.40       0.200  1.60
3         1.30       0.200  1.50
4         1.50       0.200  1.70
5         1.40       0.200  1.60
6         1.70       0.400  2.10
Run Code Online (Sandbox Code Playgroud)


Kar*_*ius 7

简而言之:您期望“求和”功能了解dplyr数据结构,例如按行分组的数据帧。sum我并没有意识到它,所以它只需要整个的和data.frame

这是一个简短的解释。这个:

select(iris, starts_with('Petal')) %>% rowwise() %>% sum()
Run Code Online (Sandbox Code Playgroud)

无需使用管道运算符即可进行以下重写:

data <- select(iris, starts_with('Petal'))
data <- rowwise(data)
sum(data)
Run Code Online (Sandbox Code Playgroud)

如您所见,您正在构造一个称为的东西tibble。然后,rowwise调用将添加有关此对象的其他信息,并指定应按行分组。

但是只有知道这个分组等功能summarize,并mutate能正常工作像预期。类似的Base R函数sum不知道这些对象,因此将它们视为任何标准data.frames。而标准的方法sum()是对整个数据帧求和。

使用mutate作品:

select(iris, starts_with('Petal')) %>%
  rowwise() %>%
  mutate(sum = sum(Petal.Width, Petal.Length))
Run Code Online (Sandbox Code Playgroud)

结果:

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

# A tibble: 150 x 3
   Petal.Length Petal.Width   sum
          <dbl>       <dbl> <dbl>
 1         1.40       0.200  1.60
 2         1.40       0.200  1.60
 3         1.30       0.200  1.50
 ...
Run Code Online (Sandbox Code Playgroud)


LMc*_*LMc 7

select如果使用c_across来选择要求和的变量,则可以跳过使用:

iris %>% 
  rowwise() %>% 
  mutate(sum = sum(c_across(starts_with("Petal"))), .keep = "used") %>% 
  ungroup()
Run Code Online (Sandbox Code Playgroud)

输出

如果您想保留数据框中的所有列,请删除该.keep参数。

 Petal.Length Petal.Width   sum
          <dbl>       <dbl> <dbl>
 1          1.4         0.2   1.6
 2          1.4         0.2   1.6
 3          1.3         0.2   1.5
 4          1.5         0.2   1.7
 5          1.4         0.2   1.6
 6          1.7         0.4   2.1
 7          1.4         0.3   1.7
 8          1.5         0.2   1.7
 9          1.4         0.2   1.6
10          1.5         0.1   1.6
# ... with 140 more rows
Run Code Online (Sandbox Code Playgroud)

同样,与max

iris %>% 
    rowwise() %>% 
    mutate(max = max(c_across(starts_with("Petal"))), .keep = "used") %>% 
    ungroup()
Run Code Online (Sandbox Code Playgroud)

笔记

如果按行聚合函数已经存在,它很可能比使用rowwise. 例如,要获取行总和,可以在基 R 中使用逐行聚合函数rowSums,并且可以使用across not c_across来实现:

# dplyr 1.1.0 use pick instead of across
iris %>% 
  mutate(sum = rowSums(across(starts_with("Petal"))), .keep = "used")
Run Code Online (Sandbox Code Playgroud)