2016-03-18 4 views
1

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

dat <- data.frame(code = c("A11", "B22", "C33"), 
        age = c(NA, NA, 12), 
        sex = c(NA, NA, 2), 
        more = c(7, 4, 9), 
        stringsAsFactors = FALSE) 

age.and.sex <- read.table(textConnection(" 
code age sex 
A11 15 2 
B22 10 1 
"), header = TRUE, stringsAsFactors = FALSE) 

joined <- merge(dat, age.and.sex, by="code", all.x=TRUE) 

joined 
    code age.x sex.x more age.y sex.y 
1 A11 NA NA 7 15  2 
2 B22 NA NA 4 10  1 
3 C33 12  2 9 NA NA 

Теперь, когда я пытаюсь скопировать значения из двух новых столбцов («age.y» «sex.y») в двух старых («age.x», «sex.y»), это работает для одной колонки, но с другой я получаю любопытное предупреждение:

joined[is.na(joined$age.x)]$age.x <- joined$age.y 
joined[is.na(joined$sex.x)]$sex.x <- joined$sex.y 
Warning message: 
In `[<-.data.frame`(`*tmp*`, is.na(joined$sex.x), value = list(code = c("A11", : 
    provided 5 variables to replace 4 variables 

Что здесь происходит?

ответ

1

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

> joined[is.na(joined$age.x)] 
    code age.x more age.y 
1 A11 NA 7 15 
2 B22 NA 4 10 
3 C33 12 9 NA 

Я предполагаю, что вы хотите сделать, это следующее:

joined[is.na(joined$age.x),]$age.x <- joined$age.y[is.na(joined$age.x)] 
joined[is.na(joined$sex.x),]$sex.x <- joined$sex.y[is.na(joined$sex.x)] 
+2

Я думаю, 'присоединился $ age.x [is.na (присоединился $ age.x)]' может быть более эффективным. – nicola

+1

Я старался оставаться рядом с решением OPs, чтобы он был более поучительным. Я согласен с тем, что ваш путь или предложенный один йоран были бы предпочтительнее. –

+0

@nicola Почему это более эффективно? –

4

Обе эти колонки «замены» совершенно неправильно, но давайте сосредоточимся на второй, так как первый из них безмолвно удалился более или менее случайно.

Так давайте пройдем через линию

joined[is.na(joined$sex.x)]$sex.x <- joined$sex.y 

шаг за шагом.

Так что начните с тем, что is.na() часть собирается вернуться:

is.na(joined$sex.x) 
[1] TRUE TRUE FALSE 

Логическое вектор длины три. Ок, я думаю. Теперь что происходит, когда мы по существу делаем joined[c(T,T,F)]?

> joined[is.na(joined$sex.x)] 
    code age.x more age.y 
1 A11 15 7 15 
2 B22 10 4 10 
3 C33 NA 9 NA 

Бьюсь об заклад, вы этого не ожидали! R считает, что вы выбираете столбцы, перерабатывает булеву вектор и выбирает столбцы 1, 2, 4 и 5. Обратите внимание, что sex.x нет вообще:

> joined[is.na(joined$sex.x)]$sex.x 
NULL 

На этом этапе должно быть совершенно ясно, почему вы получили предупреждение. Вы пытались присвоить то, чего не было.

Первая попытка не удалась (она скопировала NA из колонки .y, что, вероятно, не то, что вы хотели). Но вам просто повезло, что колонка, которую вы хотели, присутствовала вообще.

В целом, замена и подмножество, вероятно, является хрупким способом для этого, вы, вероятно, ищете функцию coalesce.

Смежные вопросы