2016-11-12 2 views
1

Я унаследовал некоторый старый код R для работы с этим, переписывая некоторые значения в столбце на основе значения в другом столбце той же строки который был ошибочно считается логическое значение, когда, в действительности, эти значения были на самом деле (строки преобразуются в) факторы, например, так:R: Случайное подмножество фрейма данных с использованием столбца факторов, как если бы оно было логическим

df <- data.frame(value = c(1, 2, 3, 4, 5, 6), 
       reversed = c("true", "false", 
           "true", "true", 
           "false", "false")) 

str(df) 
#> 'data.frame': 6 obs. of 2 variables: 
#> $ value : num 1 2 3 4 5 6 
#> $ reversed: Factor w/ 2 levels "false","true": 2 1 2 2 1 1 

df$recoded_value <- df$value 
df$recoded_value[df$reversed] <- 7 - df$recoded_value[df$reversed] 

Если вы проверяете результаты, это приводит к непредвиденным результатам. df[2, "recoded_value"] - 5, но цель состоит в том, чтобы он был 2. Кроме того, df[3, "recoded_value"] - это 3, но для него должно быть 4.

Я хотел бы понять, что здесь происходит. Моя первая гипотеза заключалась в том, что R обрабатывал один факторный уровень как TRUE, а другой как FALSE. Но это, очевидно, не так, потому что одинаковые уровни фактора являются не обращаются одинаково:

df[c(1,3), ] 
#> value reversed recoded_value 
#> 1  1  true    6 
#> 3  3  true    3 

df[c(2,5), ] 
#> value reversed recoded_value 
#> 2  2 false    5 
#> 5  5 false    5 

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

Чтобы уточнить: меня не интересуют решения проблемы. Я знаю, как исправить код для получения ожидаемых результатов. Я хотел бы:

  1. Почему этот код работает вообще? Как вы можете подмножество на основе столбца факторов? Что такое `[`, чтобы это разрешить?
  2. Почему одинаковые значения (, т. Е., одинаковый уровень фактора) обрабатываются по-разному?

ответ

1

Как отмечается в посте, reversed является factor, а не logical вектор. В R, TRUE/FALSE значения являются логическим, так преобразовать logical вектор

df$reversed <- df$reversed=="true" 

Относительно того, почему мы имеем неожиданный выход (из кода OP в),

df$reversed 
#[1] true false true true false false 
#Levels: false true 

в levels в алфавитном порядке и режим хранения factor составляет integer, т.е.

as.integer(df$reversed) 
#[1] 2 1 2 2 1 1 

Итак, когда мы Подмножество «recoded_value» с помощью «обратной», он будет подмножеством на основе числовой индекс

df$recoded_value[df$reversed] 
#[1] 2 1 2 2 1 1 

т.е. первое значение на выходе является вторым наблюдение «recoded_value», а второй 1 наблюдение и так далее, а если использовать правильный логический индекс

df$recoded_value[df$reversed=="true"] 
#[1] 1 3 4 

Давайте посмотрим, как это будет вести себя с измененным «обратными»

df$reversed <- df$reversed=="true" 
df$recoded_value[df$reversed] <- 7 - df$recoded_value[df$reversed] 
df[c(1,3), ] 
# value reversed recoded_value 
#1  1  TRUE    6 
#3  3  TRUE    4 
df[c(2,5),] 
# value reversed recoded_value 
#2  2 FALSE    2 
#5  5 FALSE    5 
+1

Спасибо за ответ! Не знаю, почему я этого раньше не осознавал. Я думаю, что я выбрал плохие числа при построении минимального примера; Я не должен был выбирать значения, идентичные номеру строки. ': -p' В любом случае, спасибо. +1 –

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