R Использование цикла for () для заполнения одного кадра данных другим - PullRequest
2 голосов
/ 02 июня 2011

У меня есть два блока данных, и я хочу вставить значения одного блока данных в другой (назовем их DF1 и DF2).

DF1 состоит из 2 столбцов 1 и 2. Столбец 1 (col1) содержит символы от a до z, а col2 имеет значения, связанные с каждым символом (от a до z)

DF2 - это кадр данных с 3 столбцами. Первые два состоят из каждой комбинации DF1$col1, так: aa ab ac ad и т. Д .; где первая буква в col1, а вторая буква в col2

Я хочу создать простую математическую модель, используя значения в DF1$col2, чтобы увидеть результаты каждой возможной комбинации объектов в DF1$col1 Первый шаг, который я хотел сделать, - это перенести значения из DF1$col2 в DF2$col3 (значения из DF2$col3 должны быть связаны со значениями в DF2col1), но вот где я застрял. У меня в настоящее время есть

for(j in 1:length(DF2$col1))
{
  ## this part is to use the characters in DF2$col1 as an input 
  ## to yield the output for DF2$col3--
  input=c(DF2$col1)[j]

  ## This is supposed to use the values found in DF1$col2 to fill in DF2$col3

  g=DF1[(DF1$col2==input),"pred"]

  ## This is so that the values will fill in DF2$col3--
  DF2$col3=g
}

Когда я запускаю это, DF2$col3 будет заполнено тем же значением для определенного символа из DF1 (например, DF2$col3 будет иметь все строки, заполненные значением, связанным с символом "a" из DF1) Что именно я делаю не так?

Спасибо большое за ваше время

Ответы [ 3 ]

4 голосов
/ 03 июня 2011

Вы действительно должны использовать merge для этого, как @Aaron предложил в своем комментарии выше, но если вы настаиваете на написании своего собственного цикла, то у вас есть проблема в последней строке, так как вы присваиваете значение g для весь столбец col3. Вы также должны использовать индекс j, например:

for(j in 1:length(DF2$col1))
{
  DF2$col3[j] = DF1[(which(DF1$col2 == DF2$col1[j]), "pred"]
}

Если это не сработает, то, пожалуйста, также опубликуйте пример базы данных, чтобы иметь возможность помочь более подробно (как я не знаю, но есть предположения, что может быть "pred").

1 голос
/ 03 июня 2011

Звучит так, будто вы пытаетесь сделать простое соединение, то есть сопоставить DF1$col1 с DF2$col1 и скопировать соответствующее значение из DF1$col2 в DF2$col3. Попробуйте это:

DF1 <- data.frame(col1=letters, col2=1:26, stringsAsFactors=FALSE)
DF2 <- expand.grid(col1=letters, col2=letters, stringsAsFactors=FALSE)
DF2$col3 <- DF1$col2[match(DF2$col1,  DF1$col1)]

При этом используется функция match(), которая, как указано в документации, «возвращает вектор позиций (первых) совпадений своего первого аргумента во втором». Значения, которые есть в DF1$col1, уникальны, поэтому с этим методом проблем не возникнет.

Как примечание: в R обычно лучше векторизовать вашу работу, чем использовать явные циклы.

0 голосов
/ 03 июня 2011

Не уверен, что я полностью понял ваш вопрос, но вы можете попробовать это:

df1 <- data.frame(col1=letters[1:26], col2=sample(1:100, 26))
df2 <- with(df1, expand.grid(col1=col1, col2=col1))
df2$col3 <- df1$col2  

Последняя команда использует переработку (она также может быть написана как rep(df1$col2, 26)).

Результаты показаны ниже:

> head(df1, n=3)
  col1 col2
1    a   68
2    b   73
3    c   45
> tail(df1, n=3)
   col1 col2
24    x   22
25    y    4
26    z   17
> head(df2, n=3)
  col1 col2 col3
1    a    a   68
2    b    a   73
3    c    a   45
> tail(df2, n=3)
    col1 col2 col3
674    x    z   22
675    y    z    4
676    z    z   17
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...