Совокупные?значения в столбце, основанные на полном списке строк из другой таблицы, несколько раз, где имена столбцов соответствуют второй таблице - PullRequest
0 голосов
/ 22 декабря 2018

Многословное название ... но не знаю, как это описать.В самом простом смысле, я думаю, что я пытаюсь агрегировать, но кажется, что это цикл агрегации?(Это приводит меня сюда, потому что все, что я читаю, говорит, что в R не используются циклы.)

У меня есть два кадра данных:

df1
ID  ID2  Ball  Ball  Ball  Square  Square  Triangle  Triangle  Triangle
1   a    1     1     0     0       0       1          1         0
1   b    0     1     0     1       1       1          0         1
2   a    1     1     0     0       0       1          1         0
3   a    1     0     1     1       0       0          1         0
3   b    0     1     1     1       1       0          1         1
4   b    0     1     1     1       1       0          1         1
5   a    1     0     1     1       0       0          1         0
5   b    0     0     0     1       1       1          1         1
6   a    0     0     1     1       0       1          1         1
6   b    0     0     0     0       1       1          1         0
7   b    0     1     0     1       1       0          1         1

df2
ID  ID2  Type
1   a    Ball
1   b    Triangle
2   a    Triangle
3   a    Square
3   b    Ball
4   b    Square
5   a    Ball
5   b    Square
6   a    Ball
6   b    Triangle
7   b    Ball

Это все общие значения.Идентификаторы намного сложнее, а не числа, а структура данных - это пара сотен столбцов на 30 000 строк.

Я пытаюсь сделать то, что суммирую столбцы, основываясь только на том, откуда взяты типы идентификаторов.df2 соответствует заголовку столбца в df1.Но у меня есть идентичные имена столбцов, и это немного сбивает меня с толку.

Для этого набора мой желаемый результат будет:

df3
    Ball  Ball  Ball  Square  Square  Triangle  Triangle  Triangle
Sum 2     3     3     3       2       3         2         1

Каждый столбец суммируется только на основе соответствияидентификаторы.Таким образом, любой столбец с именем Ball суммирует только строки, соответствующие ID 1, 5 и 7, перечисленные в df2.(и т. д. для каждого типа.)

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

df4
Ball  Square  Triangle
2.67    2.50     2.00   

Надеюсь, это имеет смысл!Из этого будет создано два фрейма данных.

РЕДАКТИРОВАТЬ: я отредактировал свои наборы данных, чтобы включить второй идентификатор, а также растянул df2, чтобы показать, что в нем больше строк, чем в df1 есть столбцы.Тип в df2 не соответствует 1 для 1 в df1.Заголовки столбцов в df1 предназначены для определения типа группы, к которой принадлежит весь набор данных.

1 Ответ

0 голосов
/ 22 декабря 2018

Попробуйте:

Type <- as.character(df2$Type)

ag <- sapply(2:ncol(df1), function(i) sum(df1[[i]] * (Type == names(df1)[i])))
tapply(ag, names(df1)[-1], mean)
##     Ball   Square Triangle 
## 2.000000 2.500000 1.333333 

или

Type <- as.character(df2$Type)
nms <- names(df1)[-1]

ag <- mapply(function(x, nm) sum(x * (Type == nm)), df1[-1], nms)
tapply(ag, nms, mean)
##     Ball   Square Triangle 
## 2.000000 2.500000 1.333333 

или:

nms <- names(df1)[-1]
Type <- as.character(df2$Type)

ag <- colSums(df1[-1] * outer(Type, nms, "=="))
tapply(ag, nms, mean)
##     Ball   Square Triangle 
## 2.000000 2.500000 1.333333 

Примечание

Ввод в воспроизводимой форме:

Lines1 <- "
ID  Ball  Ball  Ball  Square  Square  Triangle  Triangle  Triangle
1   1     1     0     0       0       1          1         0
2   0     1     0     1       1       1          0         1
3   1     1     0     0       0       1          1         0
4   1     0     1     1       0       0          1         0
5   0     1     1     1       1       0          1         1
6   0     1     1     1       1       0          1         1
7   1     0     1     1       0       0          1         0
8   0     0     0     1       1       1          1         1"
df1 <- read.table(text = Lines1, header = TRUE, check.names = FALSE)

Lines2 <- "
ID   Type
1    Ball
2    Triangle
3    Triangle
4    Square
5    Ball
6    Square
7    Ball
8    Square"
df2 <- read.table(text = Lines2, header = TRUE)
...