【问题标题】:Function in R that performs multiple operations over columns of two datasetsR中对两个数据集的列执行多项操作的函数
【发布时间】:2020-07-27 15:02:07
【问题描述】:

我有两个数据集,每个数据集有 5 列和 10,000 行。我想从两个数据集之间的列中的值计算y,数据集1中的第1列和数据集2中的第1列;然后是数据集 1 中的第 2 列和数据集 2 中的第 2 列。y 在计算之前需要遵循一组规则。到目前为止我所做的一切都行不通,我无法弄清楚为什么以及是否有更简单的方法来完成所有这些操作。

  1. 从 t 分布创建数据
mx20 <- as.data.frame(replicate(10000, rt(20,19)))
mx20.50 <- as.data.frame(replicate(10000, rt(20,19)+0.5)) 
  1. 计算每个模拟样本的平均值
m20 <- apply(mx20, FUN=mean, MARGIN=2)
m20.05 <- apply(mx20.50, FUN=mean, MARGIN=2)

上述步骤 1 和 2_ 对来自 t 分布rt(30,29); rt(50,49); rt(100,99); and rt(1000,999)的五个样本大小重复

  1. 为每个 t 分布规范绑定表(创建 data.frame)
tbl <- cbind(m20, m30, m50, m100, m1000)
tbl.50 <- cbind(m20.05, m30.05, m50.05, m100.05, m1000.05)
  1. 最后,我想计算上面指定的 y。但这是我完全迷失的地方。请看下面我迄今为止的最佳尝试。

y = (mtheo-m0)/(m1-m0),其中当 m1 = m0 时 y = y。 mtheo 是一个常数(例如 0.50),m1 是 tbl 的第 1 列中的值,m0 是 tbl.50 的第 1 列中的值。

ycalc <- function(mtheo, m1, m0) {
  ifelse(m1>=m0) {
    y = (mteo-m0)/(m1-m0)
  } ifelse(m1<m0) {
    y=0
  } returnValue(y)
} 

【问题讨论】:

  • 请注意,您在步骤 1 中的行不会创建 t 实现。第一个参数是实现的数量。 IE。 mx20 &lt;- as.data.frame(rt(10000,20,19))
  • @SteveM 我希望这条线能给我来自m=0sd=1 的 t 分布的值,这些值来自n=20 的样本。 replicate 函数,因为我想要从指定的 t 分布中抽取 10,000 个样本。有错吗?

标签: r function if-statement


【解决方案1】:

你可以试试这个。我使用数据框而不是数据表。

此代码更通用。您可以添加或删除参数。以下是可用于创建 t 分布的参数。

params = data.frame(
    n = c(20, 30, 50, 100, 1000),
    df = c(19, 29, 49, 99, 999)
    )

这是一个循环,它为每个 t 分布创建所需的值。如果您已经拥有这些值(或创建这些值的代码),则可以忽略这部分。

tbl = data.frame(i = c(1:10000))
tbl.50 = data.frame(i = c(1:10000))
for (i in 1:nrow(params)) {
    mx = as.data.frame(replicate(10000, rt(params[i, 1], params[i, 2])))
    m <- apply(mx, FUN=mean, MARGIN=2)
    tbl = cbind(tbl, m)
    names(tbl)[ncol(tbl)] = paste("m", params[i, 1], sep="")
    mx.50 = as.data.frame(replicate(10000, rt(params[i, 1], params[i, 2])+.5))
    m.50 <- apply(mx.50, FUN=mean, MARGIN=2)
    tbl.50 = cbind(tbl.50, m.50)
    names(tbl.50)[ncol(tbl.50)] = paste("m", params[i, 1], ".50", sep="")
}
tbl = tbl[-1]
tbl.50 = tbl.50[-1]

这是进行计算的循环。我将它们保存在数据框(y)中。此数据框中的每一列都是您的函数应用于所有行的结果。

mtheo = .50
y = data.frame(i = c(1:10000))
for (i in 1:nrow(params)) {
    y$dum = 0
    idx = which(tbl[, i] >= tbl.50[, i])
    y[idx, ]$dum = 
                    (mtheo - tbl.50[idx, i]) / 
                    (tbl[idx, i] - tbl.50[idx, i])
    names(y)[ncol(y)] = paste("y", params[i, 1], sep="")
}
y = y[-1]

【讨论】:

  • 非常感谢!这正是我在过去 2 周里一直试图得到的结果。你的回答很优雅,易于理解,并给了我我需要的东西。非常适合我。
【解决方案2】:

如果tbl 中的第一列称为m0tbl.50 中的第一列称为m1,您可以试试这个:

mteo <- 0.5
ycalc <- ifelse(tbl$m1 >= tbl.50$m0, (mteo - tbl.50$m0)/(tbl$m1 - tbl.50$m0),
                ifelse(tbl$m1 < tbl.50$m0), 0, "no")

使用您的代码提供的相同列名,并将您的矩阵转换为数据框:

tbl <- data.frame(tbl)
tbl.50 <- data.frame(tbl.50)
mteo <- 0.5
ycalc <- ifelse(tbl$m20 >= tbl.50$m20.05, (mteo - tbl.50$m20.05)/(tbl$m20 - tbl.50$m20.05),
                ifelse(tbl$m20 < tbl.50$m20.05, "0", "no"))

这会导致:

head(ycalc)
[1] "9.22491706576716" "0"                "0"                "0"                "0"                "1.77027049630147"

【讨论】:

  • 谢谢@bttomio!这会在两个数据帧中迭代超过 5 列吗?我听说一个函数最好避免手动多次应用 ifelse。
  • 不客气,希望对您有所帮助。我编辑了我的答案。它只会执行考虑指定列的日期(m0m1)。
  • 您的回答也很有效。谢谢!不过,我发现 HaciDuru 的答案正是我想要得到的,所以我会接受他/她。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-20
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多