Как использовать dplyr `rowwise ()` номера столбцов вместо имен столбцов - PullRequest
1 голос
/ 25 апреля 2019
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 

Нет, похоже, они не работают, потому что результаты отличаются от моего оригинала. И я не могу использовать применить, если вам действительно нужно знать, почему Я сделал отдельный вопрос .

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

Как применить dplyr rowwise() с номерами столбцов вместо имен?

Ответы [ 3 ]

1 голос
/ 25 апреля 2019

Поскольку вы не обязательно знаете имена столбцов, но знаете положения столбцов, для которых вам необходимо стандартное отклонение и т. Д., Я бы изменил форму длинных данных и добавил бы столбец 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

Упорядочить столбцы по позиции, как вам нужно.

1 голос
/ 25 апреля 2019

Подход транспонирования данных, преобразования их в матрицу, вычисления стандартного отклонения, повторной транспонирования и преобразования в таблицу.

df %>%
  t %>%
  rbind(col4 = c(sd(.[c(1, 3),1]), sd(.[c(1, 3),2]))) %>%
  t %>%
  as_tibble()
1 голос
/ 25 апреля 2019

Проблема использования .[[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, как описано в посте с тегом dupe здесь

ПРИМЕЧАНИЕ. Все вышеперечисленные методы не требуют изменения формы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...