Как вычесть одну запись из другого фрейма данных в R - PullRequest
0 голосов
/ 10 января 2019

У меня есть два кадра данных. Один фрейм данных имеет только 1 запись и 3 столбца. Другой фрейм данных имеет 6 строк и 3 столбца. Теперь я хочу вычесть значения фрейма данных 1 из значений фрейма данных 2.

Пример данных:

df1 = structure(list(col1 = 2L, col2 = 3L, col3 = 4L), .Names = c("col1", 
"col2", "col3"), class = "data.frame", row.names = c(NA, -1L))

df2 = structure(list(col1 = c(1L, 2L, 4L, 5L, 6L, 3L), col2 = c(1L, 
2L, 4L, 3L, 5L, 7L), col3 = c(6L, 4L, 3L, 6L, 4L, 6L)), .Names = c("col1", "col2", "col3"), class = "data.frame", row.names = c(NA, -6L))

Окончательный результат должен быть как,

output = structure(list(col1 = c(-1L, 0L, 2L, 3L, 4L, 1L), col2 = c(-2L, 
-1L, 1L, 0L, 2L, 4L), col3 = c(2L, 0L, -1L, 2L, 0L, 2L)), .Names =      c("col1","col2", "col3"), class = "data.frame", row.names = c(NA, -6L))

Ответы [ 3 ]

0 голосов
/ 10 января 2019

Попробуйте это ..

# Creating Datasets
df1 = structure(list(col1 = 2L, col2 = 3L, col3 = 4L), .Names = c("col1", "col2", "col3"), class = "data.frame", row.names = c(NA, -1L))
df2 = structure(list(col1 = c(1L, 2L, 4L, 5L, 6L, 3L), col2 = c(1L,2L, 4L, 3L, 5L, 7L), col3 = c(6L, 4L, 3L, 6L, 4L, 6L)), .Names = c("col1", "col2", "col3"), class = "data.frame", row.names = c(NA, -6L))

# Output
data.frame(sapply(names(df1), function(i){df2[[i]] - df1[[i]]}))
#    col1 col2 col3
# 1   -1   -2    2
# 2    0   -1    0
# 3    2    1   -1
# 4    3    0    2
# 5    4    2    0
# 6    1    4    2
0 голосов
/ 10 января 2019

Мы можем использовать развертка :

x <- sweep(df2, 2, unlist(df1), "-")

#test if same as output
identical(output, x)
# [1] TRUE

Обратите внимание, это в два раза медленнее, чем mapply :

df2big <- data.frame(col1 = runif(100000),
                     col2 = runif(100000),
                     col3 = runif(100000))

microbenchmark::microbenchmark(
  mapply = data.frame(mapply("-", df2big, df1)),
  sapply = data.frame(sapply(names(df1), function(i){df2big[[i]] - df1[[i]]})),
  sweep = sweep(df2big, 2, unlist(df1), "-"))
# Unit: milliseconds
#   expr       min        lq     mean    median        uq      max neval
# mapply  5.239638  7.645213 11.49182  8.514876  9.345765 60.60949   100
# sapply  5.250756  5.518455 10.94827  8.706027 10.091841 59.09909   100
# sweep  10.572785 13.912167 21.18537 14.985525 16.737820 64.90064   100
0 голосов
/ 10 января 2019

Если вы сделаете df2 - df1 напрямую, вы получите

df2 - df1

Ошибка в Ops.data.frame (df2, df1): ‘-’ определено только для фреймов данных одинакового размера

Итак, давайте сделаем df1 того же размера, что и df2, повторяя строки, а затем вычтем

df2 - df1[rep(seq_len(nrow(df1)), nrow(df2)), ]

#  col1 col2 col3
#1   -1   -2    2
#2    0   -1    0
#3    2    1   -1
#4    3    0    2
#5    4    2    0
#6    1    4    2

Или другой вариант использует mapply без репликации строк

mapply("-", df2, df1)

Это вернет матрицу, если вы захотите вернуть фрейм данных

data.frame(mapply("-", df2, df1))

#  col1 col2 col3
#1   -1   -2    2
#2    0   -1    0
#3    2    1   -1
#4    3    0    2
#5    4    2    0
#6    1    4    2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...