Как я могу повторить вычисления для многих столбцов и сохранить результат в новом фрейме данных в R? - PullRequest
2 голосов
/ 16 июня 2019

Я никогда не использовал циклы, но теперь мне нужно повторить одно вычисление несколько раз и хочу сохранить выходные данные в новом фрейме данных.

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

df<-data.frame("running.nr" = 1:5,
               "spec1"= c(4,7,2,90,15),
               "spec2"= c(3,10,48,10,4),
               "spec3"= c(3,10,49,30,3),
               "spec4"= c(10,27,99,130,22),
               "n.id"= c(9,25,99,100,20))

. Это вычисление, которое мне нужно повторить для более чем 50 столбцов.Вывод должен быть сохранен в новом фрейме данных, также содержащем столбец «running.nr» из df

perc.comp1<-(df[,"spec1"]*100)/df$n.id
perc.comp2<-(df[,"spec2"]*100)/df$n.id
perc.comp3<-(df[,"spec3"]*100)/df$n.id
perc.comp4<-(df[,"spec4"]*100)/df$n.id

df.perc<-data.frame(df$running.nr,
                    perc.comp1,
                    perc.comp2,
                    perc.comp3,
                    perc.comp4)

Это нерабочий цикл, который я пытался сделать из приведенного выше кода менее повторяющимся:

for(col in names(df)[2:5]) {
  df[paste0(col, "_pct")] = df[x] *100/ df$n.id}

Это сообщение об ошибке, которое я получаю: «Ошибка в [.data.frame (df, x): объект« x »не найден». Однако я также не уверен, что цикл for приводит к тому, что я хочу.Спасибо за ваше время и помощь!

Ответы [ 3 ]

2 голосов
/ 16 июня 2019

Вы можете выбрать столбцы и выполнить этот расчет непосредственно

cols <- grep("spec", names(df), value = TRUE)
df[paste0(cols, "_pct")] <- (df[cols] * 100)/df$n.id

df
#  running.nr spec1 spec2 spec3 spec4 n.id spec1_pct spec2_pct spec3_pct spec4_pct
#1          1     4     3     3    10    9 44.444444  33.33333  33.33333  111.1111
#2          2     7    10    10    27   25 28.000000  40.00000  40.00000  108.0000
#3          3     2    48    49    99   99  2.020202  48.48485  49.49495  100.0000
#4          4    90    10    30   130  100 90.000000  10.00000  30.00000  130.0000
#5          5    15     4     3    22   20 75.000000  20.00000  15.00000  110.0000
1 голос
/ 16 июня 2019

Также уже есть хорошие ответы, как решить это эффективно, я все еще хочу помочь вам с вашим кодом.Имейте в виду, что for циклы в R в основном довольно медленные и dplyr ( tmfmnk ), apply или прямой расчет, такой как Ронак Шах , обеспечен быстрее, проще и более R "лайк".Но так как иногда они вам нужны, вот объяснение вашего цикла for.

В сообщении об ошибке говорится, что у вас нет df[x].Когда вы используете цикл for, вы объявляете переменную цикла.В вашем случае это col.Таким образом, вы использовали x никогда не объявляется в вашем цикле.Таким образом, решение здесь - это простое исправление опечатки:

for(col in names(df)[2:5]) {
  df[paste0(col, "_pct")] = df[col] *100/ df$n.id
}

output:

  running.nr spec1 spec2 spec3 spec4 n.id spec1_pct spec2_pct spec3_pct spec4_pct
1          1     4     3     3    10    9 44.444444  33.33333  33.33333  111.1111
2          2     7    10    10    27   25 28.000000  40.00000  40.00000  108.0000
3          3     2    48    49    99   99  2.020202  48.48485  49.49495  100.0000
4          4    90    10    30   130  100 90.000000  10.00000  30.00000  130.0000
5          5    15     4     3    22   20 75.000000  20.00000  15.00000  110.0000
1 голос
/ 16 июня 2019

Или с dplyr вы можете сделать:

df %>%
 mutate_at(vars(starts_with("spec")), list(~ . * 100/n.id))

  running.nr     spec1    spec2    spec3    spec4 n.id
1          1 44.444444 33.33333 33.33333 111.1111    9
2          2 28.000000 40.00000 40.00000 108.0000   25
3          3  2.020202 48.48485 49.49495 100.0000   99
4          4 90.000000 10.00000 30.00000 130.0000  100
5          5 75.000000 20.00000 15.00000 110.0000   20

Если вы хотите использовать его как новые переменные:

df %>%
 mutate_at(vars(starts_with("spec")), list(perc_comp = ~ . * 100/n.id))

  running.nr spec1 spec2 spec3 spec4 n.id spec1_perc_comp spec2_perc_comp spec3_perc_comp spec4_perc_comp
1          1     4     3     3    10    9       44.444444        33.33333        33.33333        111.1111
2          2     7    10    10    27   25       28.000000        40.00000        40.00000        108.0000
3          3     2    48    49    99   99        2.020202        48.48485        49.49495        100.0000
4          4    90    10    30   130  100       90.000000        10.00000        30.00000        130.0000
5          5    15     4     3    22   20       75.000000        20.00000        15.00000        110.0000

Или, если df состоит только из названий видов, "running.nr" и "n.id":

df %>%
 mutate_at(vars(-matches("(running.nr)|(n.id)")), list(perc_comp = ~ . * 100/n.id))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...