сложение нескольких наборов столбцов в г - PullRequest
0 голосов
/ 19 сентября 2018

Я пытаюсь добавить несколько наборов столбцов вместе.

Пример df:

  df <- data.frame(
  key = 1:5,
  ab0 = c(1,0,0,0,1),
  ab1 = c(0,2,1,0,0),
  ab5 = c(1,0,0,0,1),
  bc0 = c(0,1,0,2,0),
  bc1 = c(2,0,0,0,0),
  bc5 = c(0,2,1,0,1),
  df0 = c(0,0,0,1,0),
  df1 = c(1,0,3,0,0),
  df5 = c(1,0,0,0,6)
)

Предоставление мне:

  key ab0 ab1 ab5 bc0 bc1 bc5 df0 df1 df5
1   1   1   0   1   0   2   0   0   1   1
2   2   0   2   0   1   0   2   0   0   0
3   3   0   1   0   0   0   1   0   3   0
4   4   0   0   0   2   0   0   1   0   0
5   5   1   0   1   0   0   1   0   0   6

Я хочу добавить все наборы столбцов с 0 и 5 в них вместе и поместить их в0 столбец.

Таким образом, конечный результат будет:

  key ab0 ab1 ab5 bc0 bc1 bc5 df0 df1 df5
1   1   2   0   1   0   2   0   0   1   1
2   2   0   2   0   3   0   2   0   0   0
3   3   0   1   0   1   0   1   0   3   0
4   4   0   0   0   2   0   0   2   0   0
5   5   2   0   1   1   0   1   0   0   6

Я мог бы добавить столбцы вместе, используя 3 строки:

df$ab0 <- df$ab0 + df$ab5
df$bc0 <- df$bc0 + df$bc5
df$df0 <- df$df0 + df$df5

Но мой реальный пример имеет болеесто столбцов, поэтому я бы хотел перебрать их и использовать apply.

Имена столбцов первого набора содержатся в col0, а имена второго набора - в col5.

col0 <- c("ab0","bc0","df0")
col5 <- c("ab5","bc5","df5")

Я создал функцию для добавления столбцов в gether, используя mapply:

fun1 <- function(df,x,y) {
  df[,x] <- df[,x] + df[,y]
}

mapply(fun1,df,col0,col5)

Но я получаю ошибку: Ошибка в df [, x]: неверное количество измерений

Мысли

Ответы [ 3 ]

0 голосов
/ 19 сентября 2018

Вот подход, использующий tidyr и dplyr из метапакета tidyverse.

Сначала я приведу таблицу в длинный ("аккуратный") формат, разделю столбец на два компонента и распределю по числовой части этих компонентов.

Затем я делаювычисление, которое вы описываете.

Наконец, я возвращаю его в исходный формат, используя обратную сторону шага 1.

library(tidyverse)
df_tidy <- df %>%
  # Step 1
  gather(col, value, -key) %>%
  separate(col, into = c("grp", "num"), 2) %>%
  spread(num, value) %>%
  # Step 2
  mutate(`0` = `0` + `5`) %>%
  # Step 3, which is just the inverse of Step 1.
  gather(num, value, -key, - grp) %>%
  unite(col, c("grp", "num")) %>%
  spread(col, value)

df_tidy
key ab_0 ab_1 ab_5 bc_0 bc_1 bc_5 df_0 df_1 df_5
1   1    2    0    1    0    2    0    1    1    1
2   2    0    2    0    3    0    2    0    0    0
3   3    0    1    0    1    0    1    0    3    0
4   4    0    0    0    2    0    0    1    0    0
5   5    2    0    1    1    0    1    6    0    6
0 голосов
/ 19 сентября 2018

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

final_df <- df[grep("0", names(df))] + df[grep("5", names(df))]

final_df <- cbind(final_df, df[grep("0", names(df), invert=TRUE)])     

final_df <- final_df[order(names(final_df))]
final_df

#   ab0 ab1 ab5 bc0 bc1 bc5 df0 df1 df5 key
# 1   2   0   1   0   2   0   1   1   1   1
# 2   0   2   0   3   0   2   0   0   0   2
# 3   0   1   0   1   0   1   0   3   0   3
# 4   0   0   0   2   0   0   1   0   0   4
# 5   2   0   1   1   0   1   6   0   6   5

Rextester demo

0 голосов
/ 19 сентября 2018

Вы можете использовать map2 из пакета purrr для итерации по двум векторам одновременно:

df <- data.frame(
  key = 1:5,
  ab0 = c(1,0,0,0,1),
  ab1 = c(0,2,1,0,0),
  ab5 = c(1,0,0,0,1),
  bc0 = c(0,1,0,2,0),
  bc1 = c(2,0,0,0,0),
  bc5 = c(0,2,1,0,1),
  df0 = c(0,0,0,1,0),
  df1 = c(1,0,3,0,0),
  df5 = c(1,0,0,0,6)
)

col0 <- c("ab0","bc0","df0")
col5 <- c("ab5","bc5","df5")

purrr::map2(col0, col5, function(x, y) {
  df[[x]] <<- df[[x]] + df[[y]]
})

> df
  key ab0 ab1 ab5 bc0 bc1 bc5 df0 df1 df5
1   1   2   0   1   0   2   0   1   1   1
2   2   0   2   0   3   0   2   0   0   0
3   3   0   1   0   1   0   1   0   3   0
4   4   0   0   0   2   0   0   1   0   0
5   5   2   0   1   1   0   1   6   0   6
...