【问题标题】:Assign quantitative variables to data points in the data frames in R将定量变量分配给 R 中数据框中的数据点
【发布时间】:2018-05-13 14:28:23
【问题描述】:

我正在尝试将数字 1、2 和 3 分配给具有 80 个变量和 250 个观察值(金融时间序列)的数据框。换句话说,我想根据标准将每个数据点分为 1、2 和 3:

我认为有一些iffunctions 可以做到这一点。我试图四处寻找这种方法,但我不知道如何正确地表达问题以获得良好的结果。

例如,使用构造类似于我的这个数据框。请注意,向量中的值可以更改。将dat1 中的值视为介于 1 和 5 之间的分数。

dat1 = data.frame(
  a = c(2.1,2.3,2.3), 
  b = c(3.6,3.7,3.8), 
  c = c(1.2,1.3,1.4),
  d = c(2.4, 2.3, 3.2), 
  e = c(3.9, 1.2, 3.1))

    a   b   c   d   e
1 2.1 3.6 1.2 2.4 3.9
2 2.3 3.7 1.3 2.3 1.2
3 2.3 3.8 1.4 3.2 3.1
  • 如果 dat1 中的值介于 1 和 2 之间,则赋值为 1。
  • 如果 dat1 中的值介于 2 和 3 之间,则分配值 2。
  • 如果dat1中的值大于3,则赋值为3。

我希望最终结果变成:

dat2=
  a b c d e
1 2 3 1 2 3
2 2 3 1 2 1
3 3 3 1 3 3

如果来自dat2 的数据点具有相同的要创建的值,则对来自dat1 的行求和:

dat3=
   X1  X2  X3
1 1.2 4.5 7.5
2 2.5 4.6 3.7
3 1.4 0.0 13.4

有什么方法可以实现吗?我希望这是可以理解的。

【问题讨论】:

  • ifelse,如dat1[] <- lapply(dat1, function(x) ifelse(x<2, 1, ifelse(x>3, 3, 2)))
  • 听起来像sapply(c(1,2,3), function(x) sum(dat1*(dat2 == x))),但这与示例输出不匹配。
  • @coffeinjunky 我的输出错误,但现在已编辑。您的第一个建议有效,但您的第二个建议似乎与 dat3 不匹配。
  • 你能解释一下第一行的1.2和4.5是怎么计算出来的吗?
  • dat2 中,我们看到只有c1 在第1 行中具有1 的值。所以dat1 的第1 行的sum 将变为1.2。在dat2 中,我们再次看到有 2 个具有分类值 2 的值,即数字 2.1dat1 中的 2.4,将它们相加将得到 4.5

标签: r variable-assignment assign


【解决方案1】:

使用floor获取组ID,我们使用apply

d1=floor(dat1)
d1[d1>3]=3
d1
  a b c d e
1 2 3 1 2 3
2 2 3 1 2 1
3 3 3 1 3 3

xx=cbind(d1,dat1)

bl <- apply(xx,1, function(x){
    aggregate(x[6:10], by=list(Category=x[1:5]), FUN=sum)
})

df=Reduce(function(x, y) merge(x, y, by="Category",all=T), bl)
df$Category=NULL
 t(df)
   [,1] [,2] [,3]
x.x  1.2  4.5  7.5
x.y  2.5  4.6  3.7
x    1.4   NA 13.4

【讨论】:

  • @coffeinjunky 嗯,添加d1[d1&gt;3]=3
  • 出于某种原因,我得到的d1与你不同。但我真的认为你的建议应该有效!
  • 如何为多个列执行此操作?我的真实数据集中有 80 列。
【解决方案2】:

您的条件基本上是在 dat1 上运行 floor。如果您想按行执行此操作,我会先转换为长格式,然后再转换为宽格式。这是一个使用 data.table 的示例

library(data.table)

# convert to data.table and save row id
setDT(dat1)[, id := .I]

# convert to long and the back to wide using the row id and `floor` 
dcast(melt(dat1, id = "id"), # convert to long
      id ~ ifelse(value > 3, 3, floor(value)), # convert back to wide while aggregating
      sum) # calculating sum by group
#    id   1   2    3
# 1:  1 1.2 4.5  7.5
# 2:  2 2.5 4.6  3.7
# 3:  3 1.4 0.0 13.4

【讨论】:

  • id ~ cut(value, breaks = c(1:3, Inf))
【解决方案3】:

使用 dplyr 中的 case_when() 对每一列进行变异

【讨论】:

    猜你喜欢
    • 2017-09-22
    • 2020-05-18
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 2022-08-17
    • 2012-08-14
    • 1970-01-01
    • 2017-10-16
    相关资源
    最近更新 更多