首页 > 解决方案 > 如何使用 dplyr `rowwise()` 列号而不是列名

问题描述

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 

不,看起来这些不起作用,因为结果与我原来的不同。如果你真的需要知道我为什么提出一个单独的问题,我不能使用 apply 。

df %>% mutate(col4 = apply(.[, c(1, 3)], 1, sd))

如何rowwise()使用列号而不是名称应用 dplyr?

标签: rdplyr

解决方案


使用.[[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

或者另一种选择是mappurrr我们循环的地方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

当然,最简单的方法是使用rowSdsfrom ,如此matrixStats的 dupe 标记帖子中所述

注意:以上所有方法都不需要任何重塑


推荐阅读