как искать столбцы с одинаковыми именами, добавлять значения столбцов и заменять эти столбцы с одинаковыми именами их суммами?Используя R - PullRequest
5 голосов
/ 09 мая 2011

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

Может ли кто-нибудь помочь?

Ответы [ 4 ]

7 голосов
/ 09 мая 2011
> dfrm <- data.frame(a = 1:10, b= 1:10, cc= 1:10, dd=1:10, ee=1:10)
> names(dfrm) <- c("a", "a", "b", "b", "b")
> sapply(unique(names(dfrm)[duplicated(names(dfrm))]), 
      function(x) Reduce("+", dfrm[ , grep(x, names(dfrm))]) )
       a  b
 [1,]  2  3
 [2,]  4  6
 [3,]  6  9
 [4,]  8 12
 [5,] 10 15
 [6,] 12 18
 [7,] 14 21
 [8,] 16 24
 [9,] 18 27
[10,] 20 30

РЕДАКТИРОВАТЬ 2: Использование rowSums позволяет упростить первый аргумент sapply до unique(names(dfrm)) за счет необходимости не забыть включить drop = FALSE в "[":

sapply(unique(names(dfrm)), 
       function(x) rowSums( dfrm[ , grep(x, names(dfrm)), drop=FALSE]) )

Для сделкис символами NA:

sapply(unique(names(dfrm)), 
      function(x) apply(dfrm[grep(x, names(dfrm))], 1, 
              function(y) if ( all(is.na(y)) ) {NA} else { sum(y, na.rm=TRUE) }
       )               )

(Редактировать примечание: обратился к контрпримеру Томми, поместив уникальную конструкцию вокруг имен (.) [.]. Ошибочный код:

sapply(names(dfrm)[unique(duplicated(names(dfrm)))], 
     function(x) Reduce("+", dfrm[ , grep(x, names(dfrm))]) )
4 голосов
/ 09 мая 2011

Вот мой единственный лайнер

# transpose data frame, sum by group = rowname, transpose back.
t(rowsum(t(dfrm), group = rownames(t(dfrm))))
2 голосов
/ 09 мая 2011

Некоторые примеры данных.

dfr <- data.frame(
  foo = rnorm(20),
  bar = 1:20,
  bar = runif(20),
  check.names = FALSE
)

Метод: цикл по уникальным именам столбцов;если есть только одно из этого имени, то выбор всех столбцов с этим nme вернет вектор, но если есть дубликаты, это также будет фрейм данных.Используйте rowSums для суммирования по строкам.( Дух. РЕДАКТИРОВАТЬ: Не совсем "Дух", как считалось ранее!) lapply возвращает список, который нам нужно преобразовать в фрейм данных, и, наконец, мы исправляем имена. РЕДАКТИРОВАТЬ: sapply избегает необходимости в последнем шаге.

unique_col_names <- unique(colnames(dfr))
new_dfr <- sapply(unique_col_names, function(name)
{
  subs <- dfr[, colnames(dfr) == name]
  if(is.data.frame(subs))
    rowSums(subs)
  else
    subs
})
1 голос
/ 09 мая 2011

Один из способов - идентифицировать дубликаты, используя (неожиданно) функцию duplicated, а затем выполнить цикл по ним, чтобы вычислить суммы. Вот пример:

dat.dup <- data.frame(x=1:10, x=1:10, x=1:10, y=1:10, y=1:10, z=1:10, check.names=FALSE)
dups <- unique(names(dat.dup)[duplicated(names(dat.dup))])
for (i in dups) {
dat.dup[[i]] <- rowSums(dat.dup[names(dat.dup) == i])
}
dat <- dat.dup[!duplicated(names(dat.dup))]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...