如何在r中添加按特定级别的值缩放的列?

时间:2016-06-03 16:52:23

标签: r

我有这样的数据集(注意标题IJValue):

myData = read.table(text="
I J Value\n
A X 5
A Y 10
A Z 20
B X 80
B Y 120
B Z 40
C X 30
C Y 60
C Z 90", header = TRUE)

问题:

我想向RelValue添加一个列(称为myData),其值等于Value的值I,其中J ZRelValue(I,J) = Value(I,J)/Value(I|J=Z)

等式看起来像这样: RelValue

所以添加的列RelValue 0.25 0.5 1.0 2.0 3.0 1.0 1/3 2/3 1.0 应该像这样结束:

DirectoryInfo di = new DirectoryInfo(somePath);
List<FileInfo> files = di.GetFiles("*.txt"); // grab all text files in path
Parallel.ForEach(files, currFile => ProcessFile(currFile));

关于我如何做到这一点的任何想法?(来自java我没有成功地与循环战斗数小时 - 但是现在我必须更容易在R中)。

提前致谢。

2 个答案:

答案 0 :(得分:2)

我们可以尝试使用data.table。转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(myData),按&#34; I&#34;分组,我们划分&#39;价值&#39;通过&#39;价值&#39;在哪里&#39; J&#39;是&#39; Z&#39; (假设每个&#39; I&#39;组中的&#39; J&#39;列只有一个唯一的&#39; Z)并指定它(:=)来创建一个新栏目。

library(data.table)
setDT(myData)[, RelValue := round(Value/Value[J=="Z"],2) , by = I]

或者使用dplyr,我们使用类似的方法。

library(dplyr)
myData %>%
       group_by(I) %>%
       mutate(RelValue = round(Value/Value[J=="Z"], 2))
#       I      J Value RelValue
#  <fctr> <fctr> <int>    <dbl>
#1      A      X     5     0.25
#2      A      Y    10     0.50
#3      A      Z    20     1.00
#4      B      X    80     2.00
#5      B      Y   120     3.00
#6      B      Z    40     1.00
#7      C      X    30     0.33
#8      C      Y    60     0.67
#9      C      Z    90     1.00

或使用ave

with(myData, round(Value/ave(Value * (J=="Z"), I, FUN = max),2))
#[1] 0.25 0.50 1.00 2.00 3.00 1.00 0.33 0.67 1.00

答案 1 :(得分:1)

以下是使用splitlapply的另一个基本R方法:

unlist(lapply(split(myData, myData$I), function(i) {
                                       round(i$Value / i[i$J == "Z", "Value"], 2)}))

split函数将data.frame分区为I.然后lapply遍历每个分区并应用该函数。最后,由于lapply会返回一个列表,我们会使用unlist将其转换为矢量。