как заменить значения в матрице, если они имеют одинаковое начало? - PullRequest
0 голосов
/ 20 мая 2018

У меня большая матрица с продуктами.Некоторые значения идентичны, но имеют разные имена.Например:

Ketchup  Ketchupwithgarlic  Ketchupspicy Chips Chipsorganic
0               1               0         0      1
1               0               0         0      0
0               0               0         1      0
1               0               0         0      0

Я хочу объединить эти два вектора в один вектор, если одно имя начинается с одного и того же имени, поэтому выходные данные выглядят так:

Ketchup Chips
1        1
1        0
0        1
1        0

что мне делать?

Ответы [ 3 ]

0 голосов
/ 20 мая 2018

Я верю, что это делает то, что вы хотите.По крайней мере с предоставленным вами набором данных.И это не зависит от жестко закодированных имен столбцов.

С данными, прочитанными кодом в ответе @MKR:

nms <- names(df)
inx <- which(sapply(seq_along(nms), function(i) any(grepl(paste0("^", nms[i]), nms[-i]))))
result <- sapply(inx, function(i) rowSums(df[, grep(nms[i], nms)]))
colnames(result) <- nms[inx]
result
#     Ketchup Chips
#[1,]       1     1
#[2,]       1     0
#[3,]       0     1
#[4,]       1     0
0 голосов
/ 20 мая 2018

Вот еще одна базовая R-альтернатива.Я думаю, что ответ Руи Баррадеса, вероятно, лучше, но может быть полезно увидеть несколько подходов.

# save column names
cnms <- colnames(myMat)
# build a matrix that groups on column names using col and grepl
grps <- col(diag(length(cnms))) * sapply(cnms[order(cnms)], grepl, x=cnms)
# run through the groups and perform rowSums to collapse groups into one column
sapply(split(seq_len(ncol(myMat)), 
             colnames(grps)[apply(grps, 1, FUN=function(x) min(x[x != 0]))]),
       function(y) rowSums(myMat[, y]))

Это возвращает

     Chips Ketchup
[1,]     1       1
[2,]     0       1
[3,]     1       0
[4,]     0       1

data

myMat <-
structure(c(0L, 1L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 1L, 0L, 1L, 0L, 0L, 0L), .Dim = 4:5, .Dimnames = list(NULL, 
    c("Ketchup", "Ketchupwithgarlic", "Ketchupspicy", "Chips", 
    "Chipsorganic")))
0 голосов
/ 20 мая 2018

Опция, использующая dplyr::coalesce, может быть достигнута после преобразования вашей матрицы в data.frame.Кроме того, ячейка, имеющая значение 0, должна быть изменена на NA для применения coalesce.

library(dplyr)
# First change matrix to data.frame. The same data is created in data.frame 
# so this step can be skipped
df <- as.data.frame(df)

# Replace 0 with NA
df[df==0] <- NA

Опция № 1: Если имена столбцов меньше и известны тогда, один разподход как

bind_cols(Chips = coalesce(!!!select(df, starts_with("Chips"))), 
          Ketchup = coalesce(!!!select(df, starts_with("Ketchup"))) )
# # A tibble: 4 x 2
#   Chips Ketchup
#   <int>   <int>
# 1     1       1
# 2    NA       1
# 3     1      NA
# 4    NA       1

Вариант № 2: Общий подход можно записать в виде:

overlapName <- names(df)[mapply(function(x)sum(str_detect(names(df),x)), names(df)) >1]
library(stringr)

mapply(function(x)coalesce(!!!select(df, starts_with(x))), overlapName)
#      Ketchup Chips
# [1,]       1     1
# [2,]       1    NA
# [3,]      NA     1
# [4,]       1    NA

Данные:

df <- read.table(text = 
"Ketchup  Ketchupwithgarlic  Ketchupspicy Chips Chipsorganic
0               1               0         0      1
1               0               0         0      0
0               0               0         1      0
1               0               0         0      0",
header = TRUE, stringsAsFactors = FALSE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...