这个问题应该有一个简单,优雅的解决方案,但我无法弄明白,所以这里有:
假设我有以下数据集,并且我想使用dplyr计算每行中存在的2的数量.
set.seed(1)
ID <- LETTERS[1:5]
X1 <- sample(1:5, 5,T)
X2 <- sample(1:5, 5,T)
X3 <- sample(1:5, 5,T)
df <- data.frame(ID,X1,X2,X3)
library(dplyr)
Run Code Online (Sandbox Code Playgroud)
现在,以下工作:
df %>%
rowwise %>%
mutate(numtwos = sum(c(X1,X2,X3) == 2))
Run Code Online (Sandbox Code Playgroud)
但是,如何避免键入所有列名称?
我知道这可能是不容易做到dplyr的,但更普遍的,我想知道我怎么可以使用dplyr的mutate多列没有打字了所有列名.
eva*_*man 12
试试rowSums:
> set.seed(1)
> ID <- LETTERS[1:5]
> X1 <- sample(1:5, 5,T)
> X2 <- sample(1:5, 5,T)
> X3 <- sample(1:5, 5,T)
> df <- data.frame(ID,X1,X2,X3)
> df
ID X1 X2 X3
1 A 2 5 2
2 B 2 5 1
3 C 3 4 4
4 D 5 4 2
5 E 2 1 4
> rowSums(df == 2)
[1] 2 1 0 1 1
Run Code Online (Sandbox Code Playgroud)
或者,用dplyr:
> df %>% mutate(numtwos = rowSums(. == 2))
ID X1 X2 X3 numtwos
1 A 2 5 2 2
2 B 2 5 1 1
3 C 3 4 4 0
4 D 5 4 2 1
5 E 2 1 4 1
Run Code Online (Sandbox Code Playgroud)
这是另一种替代方案purrr:
library(purrr)
df %>%
by_row(function(x) {
sum(x[-1] == 2) },
.to = "numtwos",
.collate = "cols"
)
Run Code Online (Sandbox Code Playgroud)
这使:
#Source: local data frame [5 x 5]
#
# ID X1 X2 X3 numtwos
# <fctr> <int> <int> <int> <int>
#1 A 2 5 2 2
#2 B 2 5 1 1
#3 C 3 4 4 0
#4 D 5 4 2 1
#5 E 2 1 4 1
Run Code Online (Sandbox Code Playgroud)
正如新闻中所提到的,基于行的功能仍然在成熟dplyr:
我们仍然在弄清楚属于
dplyr什么和属于什么purrr.期待很多实验和这些功能的许多变化.
基准
我们可以看到如何rowwise()和do()比较purrr::by_row()这类问题以及它们如何"执行" rowSums()以及整洁的数据方式:
largedf <- df[rep(seq_len(nrow(df)), 10e3), ]
library(microbenchmark)
microbenchmark(
steven = largedf %>%
by_row(function(x) {
sum(x[-1] == 2) },
.to = "numtwos",
.collate = "cols"),
psidom = largedf %>%
rowwise %>%
do(data_frame(numtwos = sum(.[-1] == 2))) %>%
cbind(largedf, .),
gopala = largedf %>%
gather(key, value, -ID) %>%
group_by(ID) %>%
summarise(numtwos = sum(value == 2)) %>%
inner_join(largedf, .),
evan = largedf %>%
mutate(numtwos = rowSums(. == 2)),
times = 10L,
unit = "relative"
)
Run Code Online (Sandbox Code Playgroud)
结果:
#Unit: relative
# expr min lq mean median uq max neval cld
# steven 1225.190659 1261.466936 1267.737126 1227.762573 1276.07977 1339.841636 10 b
# psidom 3677.603240 3759.402212 3726.891458 3678.717170 3728.78828 3777.425492 10 c
# gopala 2.715005 2.684599 2.638425 2.612631 2.59827 2.572972 10 a
# evan 1.000000 1.000000 1.000000 1.000000 1.00000 1.000000 10 a
Run Code Online (Sandbox Code Playgroud)
只是想添加到@evan.oman 的答案中,以防您只想对特定列的行而不是所有列求和。您可以使用常规select和/或select_helpers函数。在这个例子中,我们不想包含X1在rowSums:
df %>%
mutate(numtwos = rowSums(select(., -X1) == 2))
ID X1 X2 X3 numtwos
1 A 2 5 2 1
2 B 2 5 1 0
3 C 3 4 4 0
4 D 5 4 2 1
5 E 2 1 4 0
Run Code Online (Sandbox Code Playgroud)