【问题标题】:multiplication of mixed dataframe with vector混合数据帧与向量的乘法
【发布时间】:2013-03-21 07:10:08
【问题描述】:

这里的R初学者:在搜索了一天多的简单答案之后,决定在这里发布我的第一个问题:

我想将数据框中的数字列与数字向量相乘(或除以)。数据框不仅包含数字,还包含字符串。在我的搜索中,我了解了 t(t(mydf) * myvec))sweep()scale()*apply() 和替换操作,但我无法找到一个聪明的函数来允许我指定哪些列被相乘而无需对数据框。

如何将 test.dat 的最后两列中的每一行与 myvec 相乘/除以,并返回一个包含结果以及未更改列的数据框>(对于数字,我可以添加一个“1”到myvec)。但是我该如何处理这些名字呢? 提前谢谢你!

正确的例子:

mydf

colnames(mydf)

myvec

【问题讨论】:

  • 您的mydf 是一个矩阵。当您rbind 时,如果没有至少一个data.frame 作为输入,则输出将“绑定”(绑定)为矩阵。请改用data.frame(.) 创建您的输入。
  • 答案仍然有效,请查看我编辑的答案。

标签: r vector dataframe


【解决方案1】:

如前所述,在您的示例中,您没有处理 data.frame。让我们先将您的数据设为data.frame

# bind the numerical values as variables (columns) of data.frame
mydf <-as.data.frame(cbind(
 c(1, 10, 3.6, 4.5, 5.4, 99), 
 c(12, 18, 9, 8.1, 7.2, 84)))

# give names to columns: 
names(mydf)<-c("somename","othername")

#multiply the wanted rows with myvec:

mydf[4:6,]<-myvec*mydf[4:6,]
mydf
  somename othername
1  1.00000  12.00000
2 10.00000  18.00000
3  3.60000   9.00000
4 40.50000  72.90000
5 54.00000  72.00000
6 16.50033  14.00028

编辑:同样,您的示例数据不是 data.frame,但是在将其调整为适当的数据框后,数值实际上是数字而不是因子,这仍然有效:

mydf[,9:10]<-myvec*mydf[,9:10]
mydf
   chr   start     end    name score strand score2  width     value     value2
1 chrX 5624624 5631869  Nudt11     2      +      1   7245 1.332e+01 96513.0000
2 chrX 5977262 6210835 Shroom4     9      +      1 233573 1.357e-04    31.6914

所以你可以使用方括号选择你想要的任何列,只要确保myvec的长度等于列数,这样你就不会因为回收而得到任何令人惊讶的结果。

【讨论】:

  • 谢谢你,@Hemmo。关于正确的数据框,我缺少一些东西。 R告诉我它是,你是如何调整它的?谢谢!
  • > class(mydf) [1] "data.frame"
  • 我尝试了以下调整,但它改变了最后一列的顺序(row2 现在在 row1 之前):
  • transform(mydf, value = as.numeric(levels(value)), value2= as.numeric(levels(value2)))
  • 啊哈:mydf2
【解决方案2】:

第一步是将你的字符矩阵mydf(它不是数据框)更改为具有命名列的数据框:

mydf2 <- setNames(as.data.frame("mode<-"(t(mydf[ , -1]), "numeric")), mydf[ , 1])

> mydf2
  somename othername
1      1.0      12.0
2     10.0      18.0
3      3.6       9.0
4      4.5       8.1
5      5.4       7.2
6     99.0      84.0

然后很容易应用与myvec的乘法:

res <- lapply(mydf2[4:6, ], "*", myvec)

用新值替换值:

mydf2[4:6, ] <- res

> mydf2
  somename othername
1  1.00000  12.00000
2 10.00000  18.00000
3  3.60000   9.00000
4 40.50000  72.90000
5 54.00000  72.00000
6 16.50033  14.00028

更新

根据您的编辑,这是一种方法:

last2 <- tail(seq_along(mydf), 2) # find the index of the last two columns

# transform columns from factor to numeric and multiplicate with vector
res <- lapply(lapply(mydf[last2], 
                     function(x) as.numeric(as.character(x))), "*", myvec)

mydf[last2] <- res # replace values

> mydf
   chr   start     end    name score strand score2  width     value     value2
1 chrX 5624624 5631869  Nudt11     2      +      1   7245 1.332e+01 96513.0000
2 chrX 5977262 6210835 Shroom4     9      +      1 233573 1.357e-04    31.6914

【讨论】:

  • 哇。那很快。谢谢你,@SvenHohenstein。你完全正确,我只是写了一个简单的例子。我实际上正在使用一个数据框,不幸的是它有多个非数字列。只要我要相乘的数字列彼此相邻以便我可以指定范围 [4:6,],此解决方案是否仍然有效? Vielen Dank!
  • @Stefan 是的,此解决方案适用于所有数字列。您还可以指定不相邻的列,例如,[4:6, c(1, 3, 5:7)]
  • @SvenHohenstein 你有什么理由喜欢lapply 而不是像我的解决方案那样的简单乘法?
  • @Hemmo 不,我只是错过了这种可能性。当然它更简单,更具可读性。
  • 如果你只有一把锤子,那么一切看起来都像钉子;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多