Удалить разделитель тысяч

Я импортировал файл Excel и получил такой фрейм данных

structure(list(A = structure(1:3, .Label = c("1.100", "2.300", 
"5.400"), class = "factor"), B = structure(c(3L, 2L, 1L), .Label = c("1.000.000", 
"500", "7.800"), class = "factor"), C = structure(1:3, .Label = c("200", 
"3.100", "4.500"), class = "factor")), .Names = c("A", "B", "C"
), row.names = c(NA, -3L), class = "data.frame")

Теперь я хотел бы преобразовать эти chars в numeric или даже integer. Однако точка (.) - это не десятичный знак, а «разделитель тысяч» (немецкий).

Как мне правильно преобразовать фрейм данных?

Я пробовал это:

df2 <- as.data.frame(apply(df1, 2, gsub, pattern = "([0-9])\\.([0-9])", replacement= "\\1\\2"))

df3 <- as.data.frame(data.matrix(df2))

однако apply, похоже, преобразует каждый столбец в список факторов. Могу ли я предотвратить это apply?


person speendo    schedule 05.04.2013    source источник
comment
Если проблема заключалась в том, что значения содержали валюту, этот вопрос также решался на уровне ввода данных с использованием функций read.*: stackoverflow.com/questions/10823241 /   -  person IRTFM    schedule 05.04.2013
comment
глядя на ответы на эти вопросы и предлагаемые здесь решения (я приму одно из них - я использовал тот, который разместил сам, но решение @juba, похоже, тоже работает), я думаю, что это не дубликат ...   -  person speendo    schedule 05.04.2013
comment
Необходимо ответить на вопрос: не, является ли его ответ дубликатом, а является ли вопрос дубликатом. Вам следует выполнить дополнительный поиск, прежде чем размещать вопросы.   -  person IRTFM    schedule 05.04.2013
comment
Я нашел stackoverflow.com/questions/2347410/ перед публикацией: OP хочет удалить запятую, я хотел удалить точку, я также не смог перевести ответы в этой ветке на мою проблему. Я не нашел stackoverflow.com/questions/10823241/ раньше, но это решает совершенно другую проблему. Я много искал перед публикацией (хотите верьте, хотите нет).   -  person speendo    schedule 05.04.2013


Ответы (2)


Вы можете использовать это:

sapply(df, function(v) {as.numeric(gsub("\\.","", as.character(v)))})

Который дает :

        A       B    C
[1,] 1100    7800  200
[2,] 2300     500 3100
[3,] 5400 1000000 4500

Это даст вам объект matrix, но вы можете обернуть его в data.frame(), если хотите.

Обратите внимание, что столбцы в ваших исходных данных - это не символы, а факторы.


Изменить: в качестве альтернативы, вместо того, чтобы оборачивать его с помощью data.frame(), вы можете сделать это, чтобы получить результат напрямую как data.frame:

# the as.character(.) is just in case it's loaded as a factor
df[] <- lapply(df, function(x) as.numeric(gsub("\\.", "", as.character(x))))
person juba    schedule 05.04.2013
comment
ой ты прав - плохой минимальный пример. В реальных данных это символы. - person speendo; 05.04.2013

Думаю, я нашел другое решение:

Необходимо использовать stringsAsFactors = FALSE.

Нравится:

df2 <- as.data.frame(apply(df1, 2, gsub, pattern = "([0-9])\\.([0-9])", replacement= "\\1\\2"), stringsAsFactors = FALSE)

df3 <- as.data.frame(data.matrix(df2))
person speendo    schedule 05.04.2013
comment
Я думаю, это просто заменит 2 точки? - person Arun; 05.04.2013
comment
как вы думаете, почему всего 2 точки? просто попробовал с structure(list(A = c("800.000.000.000", "2.034.312.421", "321.325.123.234" ), B = c("800.000.000.000", "2.034.312.421", "321.325.123.234" ), C = c("800.000.000.000", "2.034.312.421", "321.325.123.234" )), .Names = c("A", "B", "C"), row.names = c(NA, -3L), class = "data.frame") - все точки заменили. - person speendo; 05.04.2013
comment
Да, действительно, извините, я не знаю, почему я это сказал. Однако это не сработало бы, если бы число было 0,578, верно? - person Arun; 05.04.2013
comment
Думаю, тогда тоже должно сработать. В принципе, это запускает команду gsub("([0-9])\\.([0-9])", "\\1\\2", x) для каждого x в фрейме данных. Другими словами, функция ищет все шаблоны <digit1>.<digit2> и заменяет их на <digit1><digit2>. Это должно работать со всеми цифрами - проблемы могут возникнуть с шаблонами вроде <digit1>.<digit2>.<digit3>, но здесь точка все равно не будет разделителем тысяч. - person speendo; 05.04.2013
comment
о, если бы номер был просто .578, это не сработало бы, верно. Но и в этом случае точка не является разделителем тысяч. - person speendo; 05.04.2013
comment
Да, верно. Ваш ответ очень хорошо определен на вопрос ОП. - person Arun; 05.04.2013
comment
может из-за личного союза ;-) - person speendo; 05.04.2013
comment
хахаха ... только что заметил !! Боже мой! Мне необходимо вздремнуть!!! ахахаха, это слишком весело! - person Arun; 05.04.2013