dplyr rowwise sum 和其他功能,如 max
dplyr rowwise sum and other functions like max
如果我想使用 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
很好,但我本以为 rowwise
可以完成同样的事情,但事实并非如此,
> select(iris, starts_with('Petal')) %>% rowwise() %>% sum()
[1] 743.6
我特别想做的是select一组列,并创建一个新变量,每个变量的值都是select列中每一行的最大值。例如,如果我 select 编辑了 "Petal" 列,则最大值为 1.4、1.4、1.3 等等。
我可以这样做:
> select(iris, starts_with('Petal')) %>% apply(1, max)
没关系。但我很好奇为什么 rowwise
方法不起作用。我意识到我使用 rowwise
不正确,我只是不确定为什么它是错误的。
问题是尽管有 rowwise
,但整个数据框都作为点传递。要处理此问题,请使用 do
,它将点解释为仅表示当前行。另一个问题是 do
中的点会将行表示为列表,因此请适当地转换它。
library(dplyr)
iris %>%
slice(1:6) %>%
select(starts_with('Petal')) %>%
rowwise() %>%
do( (.) %>% as.data.frame %>% mutate(sum = sum(.)) ) %>%
ungroup
给予:
# 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
dplyr 1.0 - 稍后添加
既然有人问了这个问题,dplyr 1.0 已经发布了,它有 cur_data()
,可以用来简化上面的操作,不需要 do
。 rowwise
块中的 cur_data()
仅引用当前行。
iris %>%
slice(1:6) %>%
select(starts_with('Petal')) %>%
rowwise() %>%
mutate(sum = sum(cur_data())) %>%
ungroup
简而言之:您希望 "sum" 函数能够识别 dplyr
数据结构,例如按行分组的数据框。 sum
不知道它所以它只取整个 data.frame
.
的总和
这里简单解释一下。这个:
select(iris, starts_with('Petal')) %>% rowwise() %>% sum()
可以不使用管道运算符重写如下:
data <- select(iris, starts_with('Petal'))
data <- rowwise(data)
sum(data)
如您所见,您正在构建一个叫做 tibble
的东西。然后 rowwise
调用在这个对象上添加额外的信息并指定它应该被分组 row-wise.
然而,只有 summarize
和 mutate
等了解此分组的函数才能按预期工作。像 sum
这样的 Base R 函数不知道这些对象并将它们视为任何标准 data.frame
s。 sum()
的标准方法是对整个数据帧求和。
使用 mutate
有效:
select(iris, starts_with('Petal')) %>%
rowwise() %>%
mutate(sum = sum(Petal.Width, Petal.Length))
结果:
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
...
如果您使用 c_across
来 select 您要求和的变量,则可以跳过 select
的使用:
iris %>%
rowwise() %>%
mutate(sum = sum(c_across(starts_with("Petal"))), .keep = "used") %>%
ungroup()
输出
如果您想保留数据框中的所有列,请删除 .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
与max
类似:
iris %>%
rowwise() %>%
mutate(max = max(c_across(starts_with("Petal"))), .keep = "used") %>%
ungroup()
如果我想使用 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
很好,但我本以为 rowwise
可以完成同样的事情,但事实并非如此,
> select(iris, starts_with('Petal')) %>% rowwise() %>% sum()
[1] 743.6
我特别想做的是select一组列,并创建一个新变量,每个变量的值都是select列中每一行的最大值。例如,如果我 select 编辑了 "Petal" 列,则最大值为 1.4、1.4、1.3 等等。
我可以这样做:
> select(iris, starts_with('Petal')) %>% apply(1, max)
没关系。但我很好奇为什么 rowwise
方法不起作用。我意识到我使用 rowwise
不正确,我只是不确定为什么它是错误的。
问题是尽管有 rowwise
,但整个数据框都作为点传递。要处理此问题,请使用 do
,它将点解释为仅表示当前行。另一个问题是 do
中的点会将行表示为列表,因此请适当地转换它。
library(dplyr)
iris %>%
slice(1:6) %>%
select(starts_with('Petal')) %>%
rowwise() %>%
do( (.) %>% as.data.frame %>% mutate(sum = sum(.)) ) %>%
ungroup
给予:
# 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
dplyr 1.0 - 稍后添加
既然有人问了这个问题,dplyr 1.0 已经发布了,它有 cur_data()
,可以用来简化上面的操作,不需要 do
。 rowwise
块中的 cur_data()
仅引用当前行。
iris %>%
slice(1:6) %>%
select(starts_with('Petal')) %>%
rowwise() %>%
mutate(sum = sum(cur_data())) %>%
ungroup
简而言之:您希望 "sum" 函数能够识别 dplyr
数据结构,例如按行分组的数据框。 sum
不知道它所以它只取整个 data.frame
.
这里简单解释一下。这个:
select(iris, starts_with('Petal')) %>% rowwise() %>% sum()
可以不使用管道运算符重写如下:
data <- select(iris, starts_with('Petal'))
data <- rowwise(data)
sum(data)
如您所见,您正在构建一个叫做 tibble
的东西。然后 rowwise
调用在这个对象上添加额外的信息并指定它应该被分组 row-wise.
然而,只有 summarize
和 mutate
等了解此分组的函数才能按预期工作。像 sum
这样的 Base R 函数不知道这些对象并将它们视为任何标准 data.frame
s。 sum()
的标准方法是对整个数据帧求和。
使用 mutate
有效:
select(iris, starts_with('Petal')) %>%
rowwise() %>%
mutate(sum = sum(Petal.Width, Petal.Length))
结果:
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
...
如果您使用 c_across
来 select 您要求和的变量,则可以跳过 select
的使用:
iris %>%
rowwise() %>%
mutate(sum = sum(c_across(starts_with("Petal"))), .keep = "used") %>%
ungroup()
输出
如果您想保留数据框中的所有列,请删除 .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
与max
类似:
iris %>%
rowwise() %>%
mutate(max = max(c_across(starts_with("Petal"))), .keep = "used") %>%
ungroup()