Сопоставление столбцов, создание цикла в R - PullRequest
1 голос
/ 08 декабря 2010

У меня следующий вопрос:

У меня есть фрейм данных, который выглядит следующим образом.У меня есть цены, 3 X и 2 R.

Date    Name  Price  Interest
01.02.10 X  120     0.2
01.02.10 R  120     0.3
01.02.10 X  130     0.8
01.02.10 X  140     0.4
01.02.10 R  130     0.2
etc.

Я хотел бы сказать R искать пары X & R с одинаковой ценой и удалить остальные.Таким образом, это должно привести: 2 X и 2 R (в данном случае).

Date    Name  Price  Interest
01.02.10 X  120     0.2
01.02.10 R  120     0.3
01.02.10 X  130     0.8
01.02.10 R  130     0.2
etc.

Чтобы было понятнее (надеюсь): у меня много разных цен на каждую дату.В каждой строке есть X или R.На каждую дату есть много пар, например, X, Price = 120 & R, Price = 120 на Date 1. Но есть также цены, которые соответствуют только одному Имени, например, есть Price = 140 только для Name= X. Так что я бы хотел, чтобы R: проверял имена имен для одной цены (т. Е. Существует одна и та же цена для одного X и одного R) и удалял остальные.То, что на самом деле приведет к тому же результату, - это одинаковое количество X и R, потому что я ищу пары.

Извините, что не могу опубликовать то, что я пробовал.Я просто не мог придумать ничего.

Теперь к следующей проблеме: если пары есть, я хотел бы сказать R, чтобы проверить каждую строку.Если Имя X, я хочу, чтобы он рассчитал новую цену, а не просто напечатал существующую цену.Я пытался

xx <- if(Name == "X"){Price + 100*interest} else print{Price}

, но это не сработало.

Спасибо за помощь

Приветствую, Дани

1 Ответ

0 голосов
/ 08 декабря 2010

Edit: @ Комментарий Двина к Q был немного загадочным, и, поскольку моя первая попытка в части 1 Q была неправильной из-за неясного Q, я постараюсь выкупить себяс расширением комментария DWin:

[Предполагая, что dat содержит данные, которые вы цитируете в Q.] Сначала объедините dat с собой:

> foo <- merge(dat[, -4], dat, by.x = "Date", by.y = "Date")
> head(foo)
      Date Name.x Price.x Name.y Price.y Interest
1 01.02.10      X     120      X     120      0.2
2 01.02.10      X     120      R     120      0.2
3 01.02.10      X     120      X     130      0.2
4 01.02.10      X     120      X     140      0.2
5 01.02.10      X     120      R     130      0.2
6 01.02.10      R     120      X     120      0.2

Далее,выведите строки, где Price.x == Price.y и , где Name.x != Name.y

> (foo <- foo[with(foo, which(Price.x == Price.y & Name.x != Name.y)),])
       Date Name.x Price.x Name.y Price.y Interest
2  01.02.10      X     120      R     120      0.2
6  01.02.10      R     120      X     120      0.2
15 01.02.10      X     130      R     130      0.2
23 01.02.10      R     130      X     130      0.2

Затем избавьтесь от лишних столбцов:

> (foo <- foo[, -(4:5)])
       Date Name.x Price.x Interest
2  01.02.10      X     120      0.2
6  01.02.10      R     120      0.2
15 01.02.10      X     130      0.2
23 01.02.10      R     130      0.2

И, наконец, исправьтеИмена столбцов:

> names(foo) <- names(dat)
> foo
       Date Name Price Interest
2  01.02.10    X   120      0.2
6  01.02.10    R   120      0.2
15 01.02.10    X   130      0.2
23 01.02.10    R   130      0.2

Второе можно сделать с помощью ifelse

with(dat, ifelse(Name == "X", Price + 100*Interest, Price))

, что дает что-то такое

> with(dat, ifelse(Name == "X", Price + 100*Interest, Price))
[1] 140 120 150 160 130

Причина, по которой if() не работает, заключается в том, что if() принимает только скалярное логическое (один TRUE или FALSE), но Name == "X" возвращает логический вектор:

> with(dat, Name == "X")
[1]  TRUE FALSE  TRUE  TRUE FALSE

В этих случаях ifelse() - ваш друг.

...