#r
#r
Вопрос:
У меня есть фрейм данных с набором символов и чисел в каждом столбце, которые в конечном итоге считаются символьными столбцами, такими как этот:
df1 lt;- data.frame( Group = c('Type', 'State', 'Roads'), Value1 = c('A', 'Florida', 107.188887) )
Я хочу округлить количество точек данных до десятой цифры, но это кажется невозможным, учитывая, что они смешаны с другими типами данных. Есть ли способ сделать это округление с помощью R? Результат будет выглядеть так:
df_desired lt;- data.frame( Group = c('Type', 'State', 'Roads'), Value1 = c('A', 'Florida', 107.2) )
Я бы предпочел по возможности избегать поворота df.
Ответ №1:
Найдите элементы, которые являются только числовыми, и сделайте это само round
по base R
себе
i1 lt;- grep("^[0-9.] $", df1$Value1) df1$Value1[i1] lt;- round(as.numeric(df1$Value1[i1]), 1)
-выход
gt; df1 Group Value1 1 Type A 2 State Florida 3 Roads 107.2
Если это целый набор данных, используйте lapply
df1[] lt;- lapply(df1, function(x) { i1 lt;- grep("^[0-9.] $", x) x[i1] lt;- round(as.numeric(x[i1]), 1) x })
-выход
gt; df1 Group Value1 1 Type A 2 State Florida 3 Roads 107.2
Комментарии:
1. Это очень хорошо. Каков наилучший способ применить его ко всему кадру данных? К сожалению, мои данные намного длиннее, чем один столбец.
2. @NatashaR. обновил сообщение
Ответ №2:
Сначала str_detect
числовое значение, затем str_extract
оно, преобразуйте его в числовое с as.numeric
помощью , и, наконец round
, это:
library(stringr) library(dplyr) df1 %gt;% mutate(Value1 = ifelse(str_detect(Value1, "^[\d.] $"), round(as.numeric(str_extract(Value1, "^[\d.] $")),1), Value1)) Group Value1 1 Type A 2 State Florida 3 Roads 107.2
Редактировать:
Если этот тип редактирования необходимо выполнить в нескольких столбцах, вы можете mutate(across
:
df1 %gt;% mutate(across(starts_with("V"), ~ifelse(str_detect(., "^[\d.] $"), round(as.numeric(str_extract(., "^[\d.] $")),1), .))) df1 lt;- data.frame( Group = c('Type', 'State', 'Roads'), Value1 = c('A', 'Florida', 107.188887), Value2 = c('B', 'California', 234.1229997) )
Этот гораздо более лаконичный метод тоже работает (предупреждения можно игнорировать).:
df1 %gt;% mutate(across(starts_with("V"), ~ifelse(str_detect(., "^[\d.] $"), round(as.numeric(.),1), .)))