преобразовать большой кадр данных в 3 столбца - PullRequest
1 голос
/ 15 января 2020

ДАННЫЕ

df <- data.frame(a=c(1,1,1,1), b1=c(0,0,0,0), b2=c(0,0,0,0),c1=c(0,0,1,0), 
                 c2=c(0,1,0,0), e=c(0,0,0,0), d=c(0,0,0,0))
  a b1 b2 c1 c2 d e
1 1 0   0 0  0  0 0
2 1 0   0 0  1  0 0
3 1 0   0 1  0  0 0
4 1 0   0 0  0  0 0

Как я могу преобразовать их в 3 столбца в ab = a * sum (содержит ("b")) ac = a * (сумма (содержит ("c")))

Я ищу что-то похожее на transmute(df, ab=a*(sum(b1+b2)), ac=a*(sum(c1+c2)), aothers=a*(sum (!contains ("a" | "b" | "c")))

ab: a * sum(any col that contains "b")

a c: a * sum(any col that contains "c")

другие: a * sum(contains anything but a or b or c)

Ответы [ 3 ]

5 голосов
/ 15 января 2020

Базовое решение R:

df2 <- data.frame(ab = df$a * rowSums(df[, grepl("b", names(df))]),
                  ac = df$a * rowSums(df[, grepl("c", names(df))]),
                  others = df$a * rowSums(df[, !grepl("a|b|c", names(df))]))

, что дает:

> df2
  ab ac others
1  0  0      0
2  0  1      0
3  0  1      0
4  0  0      0

Альтернативное решение базы R:

p <- c("b","c")
v <- c("others", paste0("a", p))

s <- sapply(p, grepl, x = names(df)[-1])

collist <- split.default(df[-1], v[rowSums(s * col(s)) + 1L])

l <- lapply(collist, function(x) df$a * rowSums(x))

df2 <- as.data.frame(l)
2 голосов
/ 15 января 2020

Вот еще одно базовое решение R с cbind() + grep() + rowSums()

nms <- names(df)
dfout <- cbind(df[1],
               `colnames<-`(df$a*cbind(rowSums(df[grep("b",nms)]), 
                                       rowSums(df[grep("c",nms)]), 
                                       rowSums(df[grep("^[^abc]",nms)])),
                            c("ab","ac","others")))

таким, что

> dfout
  a ab ac others
1 1  0  0      0
2 1  0  1      0
3 1  0  1      0
4 1  0  0      0
2 голосов
/ 15 января 2020

Я думаю, что было бы проще управлять, если мы преобразуем данные в длинный формат, создадим новый столбец для разделения столбцов «b», «c» и «others», group_by каждый и умножим на «a " ценности.

library(dplyr)
library(tidyr)

df %>%
  mutate(row = row_number()) %>%
  pivot_longer(cols = -c(a, row)) %>%
  mutate(col = case_when(grepl('b', name) ~"ab", 
                         grepl('c', name) ~"ac", 
                         TRUE ~ "others")) %>%
  group_by(row, col) %>%
  summarise(value = sum(value * a)) %>%
  pivot_wider(names_from = col, values_from = value) %>%
  ungroup() %>%
  select(-row) 

# A tibble: 4 x 3
#     ab    ac others
#  <dbl> <dbl>  <dbl>
#1     0     0      0
#2     0     1      0
#3     0     1      0
#4     0     0      0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...