如何重复许多单个列的计算并将输出存储在R中的新数据框中?

时间:2019-06-16 09:27:21

标签: r

我从没使用过循环,但现在需要重复一次计算,并希望将输出存储在新的数据框中。

我发现一些似乎合适但无法正常工作的代码。 请找到很少的列示例

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列以上重复的计算。输出应存储在新数据框中,该数据框中还应包含df中的“ running.nr”列

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 个答案:

答案 0 :(得分:2)

您可以选择列并直接执行此计算

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 :(得分:1)

或者使用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))

答案 2 :(得分:1)

关于如何有效解决此问题,已经有了很好的答案,我仍然想为您提供代码帮助。请注意,{R}中的for循环在R中通常非常缓慢和dplyr(tmfmnk),apply或提供的Ronak Shah之类的直接计算更快,更容易且更R “喜欢”。但是由于有时您需要它们,因此在这里对您的for循环进行解释。

错误消息指出,您没有df[x]。使用for循环时,需要声明循环变量。您的情况是col。因此,您使用过的x不会在循环中声明。因此,这里的解决方案是一个简单的拼写错误修复方法:

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

输出:

  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