library(tidyverse)
df <- tibble(col1 = c(5, 2), col2 = c(6, 4), col3 = c(9, 9))
df %>% rowwise() %>% mutate(col4 = sd(c(col1, col3)))
# # A tibble: 2 x 4
# col1 col2 col3 col4
# <dbl> <dbl> <dbl> <dbl>
# 1 5 6 9 2.83
# 2 2 4 9 4.95
问了一系列问题之后,我终于可以计算出各行之间的标准差了。参见上面的代码。
但是我不能在生产代码中使用列名,因为我从中提取的数据库喜欢定期更改列名。对我来说幸运的是,相对列位置始终是相同的。
因此,我将仅使用列号。并且让我们检查一下以确保可以随便交换内容:
identical(df$col1, df[[1]])
# [1] TRUE
是的,我可以交换df[[1]]
代替df$col1
。我想我是这样做的。
df %>% rowwise() %>% mutate(col4 = sd(c(.[[1]], .[[3]])))
# # A tibble: 2 x 4
# col1 col2 col3 col4
# <dbl> <dbl> <dbl> <dbl>
# 1 5 6 9 3.40
# 2 2 4 9 3.40
df %>% rowwise() %>% {mutate(col4 = sd(c(.[[1]], .[[3]])))}
# Error in mutate_(.data, .dots = compat_as_lazy_dots(...)) :
# argument ".data" is missing, with no default
不,这些看起来不起作用,因为结果与我的原始照片不同。如果您确实需要知道为什么I made a separate question,我就不能使用apply。
df %>% mutate(col4 = apply(.[, c(1, 3)], 1, sd))
如何将dplyr rowwise()
应用于列号而不是名称?
答案 0 :(得分:1)
进行.[[1]]
后使用[[3]]
或。rowwise
(按行分组-每组只有一行)的问题是,它破坏了分组结构并提取了整个柱。为了避免这种情况,我们可以在进行row_number()
之前创建一个rowwise
列,然后根据该索引对这些列进行子集
library(dplyr)
df %>%
mutate(rn = row_number()) %>% # create a sequence of row index
rowwise %>%
mutate(col4 = sd(c(.[[1]][rn[1]], .[[3]][rn[1]]))) %>% #extract with index
select(-rn)
#Source: local data frame [2 x 4]
#Groups: <by row>
# A tibble: 2 x 4
# col1 col2 col3 col4
# <dbl> <dbl> <dbl> <dbl>
#1 5 6 9 2.83
#2 2 4 9 4.95
或者另一个选择是map
中的purrr
,我们在row_number()
上循环并对数据集的行进行子集设置
library(purrr)
df %>%
mutate(col4 = map_dbl(row_number(), ~ sd(c(df[[1]][.x], df[[3]][.x]))))
# A tibble: 2 x 4
# col1 col2 col3 col4
# <dbl> <dbl> <dbl> <dbl>
#1 5 6 9 2.83
#2 2 4 9 4.95
或者另一个选择是pmap
(如果我们不想使用row_number()
)
df %>%
mutate(col4 = pmap_dbl(.[c(1, 3)], ~ sd(c(...))))
# A tibble: 2 x 4
# col1 col2 col3 col4
# <dbl> <dbl> <dbl> <dbl>
#1 5 6 9 2.83
#2 2 4 9 4.95
当然,最简单的方法是使用rowSds
中的matrixStats
,如带假名的帖子here
注意:以上所有方法都不需要任何重塑
答案 1 :(得分:1)
由于您不一定知道列名,但是知道需要标准偏差的列的位置等,因此我将整形为长数据并添加一个ID列。您可以按位置而不是列名进行收集,方法是给出应成为键的列号,或从键中省略的列号。这样,您无需按列指定这些值,因为您已经将它们全部放在一列中。然后,您可以将这些摘要值重新添加到原始的宽形数据中。
library(dplyr)
library(tidyr)
df <- tibble(col1 = c(5, 2), col2 = c(6, 4), col3 = c(9, 9)) %>%
mutate(id = row_number())
df %>%
mutate(id = row_number()) %>%
gather(key, value, 1, 3) %>%
group_by(id) %>%
summarise(sd = sd(value)) %>%
inner_join(df, by = "id")
#> # A tibble: 2 x 5
#> id sd col1 col2 col3
#> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 1 2.83 5 6 9
#> 2 2 4.95 2 4 9
根据需要按位置重新排列列。
答案 2 :(得分:1)
一种将数据转置,转换为矩阵,计算标准偏差,再次转置并转换为小标题的方法。
df %>%
t %>%
rbind(col4 = c(sd(.[c(1, 3),1]), sd(.[c(1, 3),2]))) %>%
t %>%
as_tibble()