Как сравнить df1 и df2 неравной длины и присвоить значения в R - PullRequest
4 голосов
/ 04 декабря 2011

Это определения df1 и df2:

df1 <- data.frame(x = 1:3, y=letters[1:3])
df2 <- data.frame(x= rep(c(1,2,3),each=3))

Я хочу присвоить значение столбца y в df1 столбцу y в df2, где значение в столбце x в df1 равнозначение в столбце х df2.Как показано выше, df1 и df2 имеют неодинаковую длину.

for(i in 1:length(df2$x)){
        df2$y[i]<- df1$y[which(df1$x == df2$x[i])]
}

Я не ищу коротких путей для этого (никаких встроенных функций, пожалуйста).Я хочу выучить это правильно.

Правильна ли моя логика?Если это так, почему это не работает?

Любое руководство будет высоко оценено.

1 Ответ

2 голосов
/ 04 декабря 2011

Использование того, что вы называете «ярлыками», на самом деле является правильным способом сделать что-то в R. Но я думаю, что циклическое переключение вручную иногда является хорошим упражнением.Но в вашем «производственном коде», то есть в коде, на который вы хотите рассчитывать, используйте встроенные функции, когда они применимы.

Вам просто не хватает одного варианта для data.frame.Все остальное в порядке.Проблема заключается в том, что по умолчанию символьные векторы вводятся как factors в data.frame, а когда вы пытаетесь заменить значение значением из вектора factor, он заменяет его базовым числовым индексом этого уровня.Вот полный код:

df1 <- data.frame(x = 1:3, y=letters[1:3], stringsAsFactors=FALSE)

df2 <- data.frame(x= rep(c(1,2,3),each=3))

for(i in 1:length(df2$x)){

    df2$y[i]<- df1$y[which(df1$x == df2$x[i])]
}
df2
  x y
1 1 a
2 1 a
3 1 a
4 2 b
5 2 b
6 2 b
7 3 c
8 3 c
9 3 c

См. ?data.frame для получения дополнительной информации о stringsAsFactors опции

Поскольку вы, похоже, заинтересованы в обучении, вот способ, которым вы могли бы отладить,Предположим, ваши исходные команды находятся в файле с именем temp.R.Затем

> source('temp.R')
> ls()
[1] "df1" "df2" "i"

i остается после цикла for.Давайте использовать его так, чтобы ваши следующие команды с i работали.Вы можете переназначить значение на i, чтобы увидеть, что ваша команда выдаст для других значений.Теперь давайте начнем разбирать ваш код, чтобы увидеть, в чем проблема.

> i
[1] 9
> which(df1$x == df2$x[i])
[1] 3

Выглядит хорошо.3 - это то, что мы ожидаем, верно?

> df1$y[which(df1$x == df2$x[i])]
[1] c
Levels: a b c

Вот где вам нужно распознать: «О, это фактор!».Всякий раз, когда вы видите «Уровни», лампочка «фактор» должна загореться в вашей голове.

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

> df2$y[9]
[1] 3

Хорошо выглядит.Мы знаем, что происходит после замены, поэтому ясно, что что-то идет не так с назначением.Давайте попробуем это просто, чтобы увидеть, что происходит:

> df2$y[9] <- as.factor("c")
> df2$y[9]
[1] 1

Очевидно, что-то не так.Таким образом, мы сузили проблему до здесь.Теперь нам нужно вернуться, чтобы выяснить, почему мы заменяем фактор.Надеюсь, это приведет вас к справке data.frame.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...