我从没使用过循环,但现在需要重复一次计算,并希望将输出存储在新的数据框中。
我发现一些似乎合适但无法正常工作的代码。 请找到很少的列示例
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循环是否完全导致我想要的。感谢您的时间和帮助!
答案 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