2016-06-04 2 views
0

Я хочу округлить до двух значений десятичной цифры, которые являются маленькими и целыми значениями, большими. Я хочу получить desired.df от df.Как применить функцию к каждому элементу/ячейке data.frame?

df <- data.frame(a = c(0.123, 123.456), b = c(321.321, 0.321)) 
desired.df <- data.frame(a = c(0.12, 123), b = c(321, 0.32)) 

df 
#   a  b 
# 1 0.123 321.321 
# 2 123.456 0.321 

desired.df 
#  a  b 
# 1 0.12 321 
# 2 123 0.32 

Как это сделать? Я попытался apply и некоторые из его вариантов, очевидно, не надлежащим образом, а также раскрой * применять функции (как *apply(df, function(x) *apply(y, function(y) ...))), но без везения ...

Например, следующий не работает

round.my.way <- function(cell) { 
if(cell < 2) return(round(cell, 2)) 
else return(round(cell, 0)) 
} 

apply(df, 1:2, round.my.way) 

Любые идеи?

EDIT Я очень сожалею, что я не подчеркивала, что отправил desired.df больше имеет, вероятно, о форматировании каждой «ячейки» независимо друг от друга в кадре данных, но я не понял, что.

my.data.frame <- structure(list(mean = c(1.09586889552429, -0.488970742717109,       
717.369670482251, 1430.22132153487), sd = c(14.6805055234266,       
0.847924955832248, 3148.43113658712, 6224.1150344482), skew = c(15.4288196192469,  
-0.848099854154573, 15.6753519251057, 13.8872189273213), kurt = c(760.003399845995, 
3.42534233994167, 403.114382084221, 296.372235189872), min = c(0.0211657925274003, 
-6.63384131834086, 1.14376333333333, 1.51974013933333), X5.. = c(0.163422411626505, 
-1.94866860909688, 5.55001008333333, 8.48210945666667), X25.. = c(0.419624647887877, 
-0.940344070376478, 24.2286483333333, 40.2822858746667), median = c(0.712376790798036, 
-0.397878278400871, 79.5970091666667, 147.535862094), X75.. = c(1.11275078144806, 
0.0525922423468574, 300.39765875, 594.258755956833), X95.. = c(2.12897531610479, 
0.694437497721256, 2918.320405, 5614.78688014776), max = c(932.099715965617, 
3.36571976522158, 77776.31031, 151194.931773039), n = c(4046.23166666667, 
4046.23166666667, 4046.23166666667, 4046.23166666667)), .Names = c("mean", 
"sd", "skew", "kurt", "min", "X5..", "X25..", "median", "X75..", 
"X95..", "max", "n"), row.names = c(NA, 4L), class = "data.frame") 

С одним из моих экспериментов, я почти получить то, что я хочу:

apply(my.data.frame, c(1, 2), function(x) if(x < 2) round(x, 2) else round(x, 0)) 

производит:

 mean  sd skew kurt min X5.. X25.. median X75.. X95.. max 
1 1.10 15.00 15.00 760 0.02 0.16 0.42 0.71 1.11 2.00 932 
2 -0.49 0.85 -0.85 3 -6.63 -1.95 -0.94 -0.40 0.05 0.69  3 
3 717.00 3148.00 16.00 403 1.14 6.00 24.00 80.00 300.00 2918.00 77776 
4 1430.00 6224.00 14.00 296 1.52 8.00 40.00 148.00 594.00 5615.00 151195 
    n 
1 4046 
2 4046 
3 4046 

, которая действительно показывает последний n столбец как целые числа без знаков после запятой, но не остальные колонны!

Но я хотел бы это сотовую изменяющееся форматирование вместо:

 mean  sd skew kurt min X5.. X25.. median X75.. X95.. max 
1 1.10  15 15 760 0.02 0.16 0.42 0.71 1.11 2.00 932 
2 -0.49 0.85 -0.85 3 -6.63 -1.95 -0.94 -0.40 0.05 0.69  3 
3  717 3148 16 403 1.14  6 24  80 300 2918 77776 
4 1430 6224 14 296 1.52  8 40 148 594 5615 151195 
    n 
1 4046 
2 4046 
3 4046 
4 4046 
+0

@Zheyuan Ли По какой-то причине браузер не показывал (красный маленький значок сверху), что было 3 ответов. Удивительно. Но я, вероятно, не правильно сформулировал этот вопрос, из-за моего недостаточного знания. Я думаю, что проблема заключается в форматировании кадра данных на ячейку, а не исключительно использовании функции «round()» для каждой ячейки (как я, вероятно, ошибочно подразумеваю, что хочу). Поэтому во всех ответах 'желательно.df' имеет элемент (2, a), округленный до' 123.00', в то время как я не хочу '.00', а только целую часть,' 123'. – pidosaurus

+0

Я думаю, что этот вопрос уместен, и я буду исследовать его больше: http://stackoverflow.com/questions/17093416/write-a-dataframe-with-different-number-of-decimal-places-per-column- in-r – pidosaurus

+0

Да, это правильно, поэтому я изменил вопрос, чтобы включить только целую часть. (Я фактически изменил его через 1-2 минуты после публикации его в первый раз). – pidosaurus

ответ

1

round.my.way Вашей функция работает с apply. Используйте средний аргумент apply, как это для обеих строк и столбцов c(1,2)

apply(df,c(1,2),round.my.way) 
     a  b 
[1,] 0.12 321.00 
[2,] 123.00 0.32 

Другие, которые могли бы работать, а также,

Предположение 1: Если вы cell значение less than 2 затем в round to 2 decimal places else 0 decimal places. Это основано на функции, которую вы написали выше.

df <- data.frame(a = c(0.123, 123.456), b = c(321.321, 0.321)) 
df <- as.matrix(df) 
df1 <- ifelse(df < 2,round(df,2),round(df)) 
df1 
#   a  b 
# [1,] 0.12 321.00 
# [2,] 123.00 0.32 
df1 <- as.data.frame(df1) 

Предположение 2: От вас ожидается выход, я полагаю, что все ваши diagonal elements (row number = column number) are rounded up to 2 decimal places и отдых в 0 decimal places.Если предположение верно, то ниже здесь будет один из раствора:

df <- data.frame(a = c(0.123, 123.456), b = c(321.321, 0.321)) 
    df <- as.matrix(df) 
    df1 <- ifelse(row(df)==col(df),round(df,2),round(df)) 
    df1 
    #  [,1] [,2] 
    # [1,] 0.12 321.00 
    # [2,] 123.00 0.32 
    df1 <- as.data.frame(df1) 

Вы также можете использовать floor для печати до того десятичных знаков, но выход печатает количество цифр после десятичной как 2 или 3 в зависимости от того является самым высоким в dataframe, в данном случае мы имеем 0 и 2 так, что prints 2 decimal place for all elements, если вы round это до 3 знаков после запятой, он prints 321.000 для df[1,2] и 123.000 для df[2,1]

df <- data.frame(a = c(0.123, 123.456), b = c(321.321, 0.321)) 
df <- as.matrix(df) 
df1 <- ifelse(row(df)==col(df),round(df,2),floor(df)) 
df1 
#  [,1] [,2] 
# [1,] 0.12 321.00 
# [2,] 123.00 0.32 
df1 <- as.data.frame(df1) 

Для 3 знаков после запятой,

df1 <- ifelse(row(df)==col(df),round(df,2),round(df)) 
df1 
#  [,1] [,2] 
# [1,] 0.123 321.000 
# [2,] 123.000 0.321 
df1 <- as.data.frame(df1) 
+0

@RichardScriven Я не хочу передавать какую-либо неправильную информацию здесь, пожалуйста, исправьте меня здесь, чтобы я мог улучшить этот результат. Спасибо. –

+0

О, я вижу, да, спасибо. Если я назову надеждой, это будет иметь смысл, если положить if. Большое вам спасибо за то, что вы меня исправили. Я буду иметь в виду. –

+0

Привет, я сначала преобразовал его в матрицу, который я забыл вставить здесь, хотя код OP работает, я вставляю 'as.matrix()', который я сделал, другой мудрый результат был «списком» на самом деле , –

1

Быстрое решение с использованием data.table подход

library(data.table) 

setDT(df)[, lapply(.SD, function(x) ifelse(x < 2, round(x, 2), round(x)))] 

#>  a  b 
#> 1: 0.12 321.00 
#> 2: 123.00 0.32