【问题标题】:create vector for loop for condition from from dataframe从数据帧创建向量 for loop for 条件
【发布时间】:2017-03-20 23:16:09
【问题描述】:

我有一个数据框,类似于下面的示例,但更大(15000 行):

df.example <-structure(list(Date = structure(c(3287, 3386, 4286, 5286, 6286), class = "Date"),v1 = c(1L, 1L, 1L, 1L, 1L), v2 = c(0.60378, 12.82581, 3.55357, 4.96079, 0.0422),perc = c(0.598, 0.598, 0.609, 1, 0.609), v3 = c(-99, -99, 5.83509031198686, 4.96079,0.0692939244663383)), .Names = c("Date", "v1", "v2", "perc", "v3"), row.names = c(1L, 100L, 1000L, 2000L, 3000L), class = "data.frame")

df.example:

       Date     v1       v2  perc           v3
1    1979-01-01  1  0.60378 0.598 -99.00000000
100  1979-04-10  1 12.82581 0.598 -99.00000000
1000 1981-09-26  1  3.55357 0.609   5.83509031
2000 1984-06-22  1  4.96079 1.000   4.96079000
3000 1987-03-19  1  0.04220 0.609   0.06929392

我想做的是计算列“perc”中低于“某个阈值”的行的百分比。我想为多个“某些阈值”多次执行此操作,如下所示:

### "certain threshold values":
seq(from =0, to = 1, by = 0.1)


### formula to be repeated/iterated/looped: (the i stands for "certain value")
100*sum(df.example$perc<=i)/nrow(df.example)

我希望结果是一个名为“vector1”的向量,如下例所示:

vector1 <- c(0,0,0,0,0,0,0.2,0.6,0.6,0.6,1.0)    

这是我目前所拥有的,但它不起作用:

### create vector to store calculated values in
vector1=c()
vector1[1]=3

### loop calculation of percentage of rows that are below "certain threshold value" in column df.example$perc
for(i in seq(0,1, by=0.1)){
vector1[i]=sum(df.example$perc<=i)/nrow(df.example)
}

我只得到一个值,我希望它是我的 vector1 的最后一个值。

我已经在 SO 中查看过类似的主题,如 R create a vector with loop structure &How to make a vector using a for loop

有什么建议吗?

顺便说一句: 如果我使用的 dput() 没有创建要使用的数据,请发表评论,这是我第一次使用 dput()。

【问题讨论】:

  • 你可能还需要s1 &lt;- seq(0, 1, 0.5); for(i in seq_along(s1)){vector1[i]=sum(df.example$perc&lt;=s1[i])/nrow(df.example) },初始化vector1 &lt;- numeric(nrow(df.example))
  • 区别:for(i in seq_along(seq(0,1, by=0.1))){print(i)} 和 for(i in seq(0,1, by=0.1) ){print(i)} 将为您解释解决方案

标签: r for-loop vector dataframe


【解决方案1】:

关于行数,不需要每次都计算,可以赋值给变量。然后你可以使用sapply:

nrow_df <- nrow(df.example)
sapply(seq(from =0, to = 1, by = 0.1), function(x) sum(df.example$perc<=x)/nrow_df)
# [1] 0.0 0.0 0.0 0.0 0.0 0.0 0.4 0.8 0.8 0.8 1.0

或(矢量化)

indx <- seq(0, 1, by=0.1)
rowSums(df.example$perc <= matrix(indx, length(indx), nrow(df.example))) / nrow(df.example)
## [1] 0.0 0.0 0.0 0.0 0.0 0.0 0.4 0.8 0.8 0.8 1.0

【讨论】:

    【解决方案2】:

    我们需要初始化vector1,并循环遍历for循环中的序列。

    s1 <- seq(0, 1, 0.1)
    vector1 <- numeric(nrow(df.example))
    for(i in seq_along(s1)){
       vector1[i]=sum(df.example$perc<=s1[i])/nrow(df.example)
     }
    vector1
    #[1] 0.0 0.0 0.0 0.0 0.0 0.0 0.4 0.8 0.8 0.8 1.0
    

    或者矢量化方法是

    rowSums(outer(s1, df.example$perc, FUN = `>=`))/nrow(df.example)
    #[1] 0.0 0.0 0.0 0.0 0.0 0.0 0.4 0.8 0.8 0.8 1.0
    

    【讨论】:

    • 您的第二种矢量化方法也适用于更大的数据集。第一种方法没有。感谢您的帮助!
    【解决方案3】:

    这是使用outercolSums的第四种方法:

    colSums(outer(df.example$perc, seq(from=0, to=1, by=0.1), "<=")) / nrow(df.example)
    [1] 0.0 0.0 0.0 0.0 0.0 0.0 0.4 0.8 0.8 0.8 1.0
    

    outer 创建一个逻辑矩阵,显示对每个阈值元素对执行阈值测试。 “成功”用 colSums 沿列求和,然后这个计数除以测试的元素数。

    【讨论】:

      猜你喜欢
      • 2014-08-05
      • 2022-11-17
      • 2020-03-10
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-03
      • 2012-04-01
      相关资源
      最近更新 更多