【问题标题】:r function or loop to create new columns and calculate values based upon limitsr 函数或循环以创建新列并根据限制计算值
【发布时间】:2014-07-09 14:55:43
【问题描述】:

如果满足某些条件,我目前使用 40 行代码来创建和计算新列。我试图想出一种方法来将所有这些代码变成一个循环或函数来简化我的脚本。

这里是一些示例数据:

set.seed(1)
dat <- data.frame(sc1 = sample(LETTERS[1:6],15,replace=T),
                  sc1_n = sample (1:100,15),
                  sc2 = sample(LETTERS[1:6],15,replace=T),
                  sc2_n = sample (1:100,15),
                  sc3 = sample(LETTERS[1:6],15,replace=T),
                  sc3_n = sample (1:100,15),
                  ec1 = sample(LETTERS[1:6],15,replace=T),
                  ec1_n = sample (1:100,15),
                  ec2 = sample(LETTERS[1:6],15,replace=T),
                  ec2_n = sample (1:100,15),
                  ec3 = sample(LETTERS[1:6],15,replace=T),
                  ec3_n = sample (1:100,15),
                  area = sample (1:100,15))

我遍历 sc1 (A-F, n=6)、sc2 (A-F, n=6) 和 sc3 (A-F, n=6) 的每个唯一值来计算一个值,然后将这些唯一值加在一起创建另一列,称为 A、B、C、D、E 或 F,后面附加“s”表示它是 s 的值,而不是 e,在完成 sc1、sc2 和sc3。

这是我目前用来生成我需要的列和值的 40 行代码:

dat <- transform(dat,A1s = (sc1_n * 0.01) * (area) * (sc1 == "A")) #create new column A1s, and calculates a number if sc1=='A'
dat <- transform(dat,A2s = (sc2_n * 0.01) * (area) * (sc2 == "A")) #create new column A2s, and calculates a number if sc2=='A'
dat <- transform(dat,A3s = (sc3_n * 0.01) * (area) * (sc3 == "A")) #same as above, except A3s and where sc3='A'
dat <- transform(dat,As = A1s + A2s + A3s) #I really don't need A1s, A2s, or A3s, except to calculate this column, As
dat <- transform(dat,B1s = (sc1_n * 0.01) * (area) * (sc1 == "B"))
dat <- transform(dat,B2s = (sc2_n * 0.01) * (area) * (sc2 == "B"))
dat <- transform(dat,B3s = (sc3_n * 0.01) * (area) * (sc3 == "B"))
dat <- transform(dat,Bs = B1s + B2s + B3s)
dat <- transform(dat,C1s = (sc1_n * 0.01) * (area) * (sc1 == "C"))
dat <- transform(dat,C2s = (sc2_n * 0.01) * (area) * (sc2 == "C"))
dat <- transform(dat,C3s = (sc3_n * 0.01) * (area) * (sc3 == "C"))
dat <- transform(dat,Cs = C1s + C2s + C3s)
dat <- transform(dat,D1s = (sc1_n * 0.01) * (area) * (sc1 == "D"))
dat <- transform(dat,D2s = (sc2_n * 0.01) * (area) * (sc2 == "D"))
dat <- transform(dat,D3s = (sc3_n * 0.01) * (area) * (sc3 == "D"))
dat <- transform(dat,Ds = D1s + D2s + D3s)
dat <- transform(dat,E1s = (sc1_n * 0.01) * (area) * (sc1 == "E"))
dat <- transform(dat,E2s = (sc2_n * 0.01) * (area) * (sc2 == "E"))
dat <- transform(dat,E3s = (sc3_n * 0.01) * (area) * (sc3 == "E"))
dat <- transform(dat,Es = E1s + E2s + E3s)
dat <- transform(dat,F1s = (sc1_n * 0.01) * (area) * (sc1 == "F"))
dat <- transform(dat,F2s = (sc2_n * 0.01) * (area) * (sc2 == "F"))
dat <- transform(dat,F3s = (sc3_n * 0.01) * (area) * (sc3 == "F"))
dat <- transform(dat,Fs = F1s + F2s + F3s)

dat <- transform(dat,A1e = (ec1_n * 0.01) * (area) * (ec1 == "A"))
dat <- transform(dat,A2e = (ec2_n * 0.01) * (area) * (ec2 == "A"))
dat <- transform(dat,A3e = (ec3_n * 0.01) * (area) * (ec3 == "A"))
dat <- transform(dat,Ae = A1e + A2e + A3e)
dat <- transform(dat,B1e = (ec1_n * 0.01) * (area) * (ec1 == "B"))
dat <- transform(dat,B2e = (ec2_n * 0.01) * (area) * (ec2 == "B"))
dat <- transform(dat,B3e = (ec3_n * 0.01) * (area) * (ec3 == "B"))
dat <- transform(dat,Be = B1e + B2e + B3e)
dat <- transform(dat,C1e = (ec1_n * 0.01) * (area) * (ec1 == "C"))
dat <- transform(dat,C2e = (ec2_n * 0.01) * (area) * (ec2 == "C"))
dat <- transform(dat,C3e = (ec3_n * 0.01) * (area) * (ec3 == "C"))
dat <- transform(dat,Ce = C1e + C2e + C3e)
dat <- transform(dat,D1e = (ec1_n * 0.01) * (area) * (ec1 == "D"))
dat <- transform(dat,D2e = (ec2_n * 0.01) * (area) * (ec2 == "D"))
dat <- transform(dat,D3e = (ec3_n * 0.01) * (area) * (ec3 == "D"))
dat <- transform(dat,De = D1e + D2e + D3e)
dat <- transform(dat,E1e = (ec1_n * 0.01) * (area) * (ec1 == "E"))
dat <- transform(dat,E2e = (ec2_n * 0.01) * (area) * (ec2 == "E"))
dat <- transform(dat,E3e = (ec3_n * 0.01) * (area) * (ec3 == "E"))
dat <- transform(dat,Ee = E1e + E2e + E3e)
dat <- transform(dat,F1e = (ec1_n * 0.01) * (area) * (ec1 == "F"))
dat <- transform(dat,F2e = (ec2_n * 0.01) * (area) * (ec2 == "F"))
dat <- transform(dat,F3e = (ec3_n * 0.01) * (area) * (ec3 == "F"))
dat <- transform(dat,Fe = F1e + F2e + F3e)

我确信必须有一种方法可以通过创建列表和循环或至少是一个函数来智能有效地做到这一点,但我一直在寻找并没有找到方法。

-al

【问题讨论】:

    标签: r function loops transform


    【解决方案1】:

    这样的转换怎么样

    for(p in c("s","e")) {
       g <- dat[, paste0(p, "c",1:3)]
       n <- dat[, paste0(p, "c",1:3,"_n")]
       for(x in LETTERS[1:5]) {
           dat[, paste0(x,p) ] <- rowSums(n * 0.01 * (g==x) * dat$area)
       }
    }
    

    在这里,我们遍历“s”和“e”前缀的不同集合,并提取与该前缀相关的列子集。接下来,我们遍历所有组并计算该组的行总和。在这里,我们试图尽可能多地利用存储在列名中的信息。这不会创建您不需要的临时列(A1s、A2s 等)

    【讨论】:

    • 我认为这正是我所需要的。我还有一个问题。在“for”行中,您有 LETTERS,它适用于我提供的数据,但是,我的真实数据具有诸如“forest_closed”、“forest_open”等带有一类字符的值。有什么简单的方法可以切换以使其适用于我的真实数据吗?否则,我认为这个循环应该很好用!
    • 您可以将LETTERS[1:5] 替换为您喜欢的任何向量。你可以做for (x in c("forest_closted","forest_open"))
    • 对不起,另一个问题。您正在为 's' 和 'e' 前缀循环不同的集合。如果我想循环基于“start_class”和“end_class”的不同集合怎么办?
    • 我不知道 start_class 和 end_class 是什么。基本上我只是使用paste() 来构建列名,这样我就可以索引data.frame 的子集。如果你可以构建它,你可以提取它。
    • 我想我要问的是 c('s','e')) 究竟是如何工作的。它是否正在搜索以“s”和“e”开头的任何列并将它们添加到循环中?如果是,我可以改为搜索名为“开始”和“结束”的列吗?我已将 c('start','end')) 中的 p 修改为 p,但出现错误:[.data.frame(dat, , paste0(p, "c", 1:3)) 中的错误:未定义的列已选中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多