2015-03-31 74 views
0

我正在寻找使用计算值填充新数据框列,该计算值对每个数据子组都是唯一的。这里是我的确切代码:用新值在df中填充新列

df <- read.csv('data_30_Mar2015.csv') 


df$dCT <- NA 

#FUNCTION 
calc_dCT <- function(sample, DF){ 

sample_df <- DF[ which(DF$Sample=='sample'),] 
print (sample_df) 
VIC <- sample_df[ which(sample_df$Reporter=='VIC'),] 
FAM <- sample_df[ which(sample_df$Reporter=='FAM'),] 

VIC_mean<-mean(VIC[,3]) 
FAM_mean<-mean(FAM[,3]) 

DCT <- FAM_mean - VIC_mean 

for (i in 1:length(sample_df)){ 
    sample_df[i,4] <- DCT 
    } 
DF<-merge(DF, sample_df, all=TRUE) 
} 

#CALLS TO FUNCTION 
calc_dCT('c48', df) 
calc_dCT('m48', df) 
calc_dCT('c72', df) 
calc_dCT('m72', df) 

print (df) 

这里是输出:

calc_dCT('c48', df) 
[1] Sample Reporter CT  dCT  
<0 rows> (or 0-length row.names) 
calc_dCT('m48', df) 
[1] Sample Reporter CT  dCT  
<0 rows> (or 0-length row.names) 
calc_dCT('c72', df) 
[1] Sample Reporter CT  dCT  
<0 rows> (or 0-length row.names) 
calc_dCT('m72', df) 
[1] Sample Reporter CT  dCT  
<0 rows> (or 0-length row.names) 

print (df) 
Sample Reporter  CT dCT 
1  m48  VIC 27.50595 NA 
2  m48  VIC 27.77835 NA 
3  m48  VIC 27.62321 NA 
4  m48  FAM 30.87295 NA 
5  m48  FAM 30.87967 NA 
6  m48  FAM 30.73427 NA 
7  c48  VIC 26.56715 NA 
8  c48  VIC 26.89787 NA 
9  c48  VIC 26.82587 NA 
10 c48  FAM 30.20642 NA 
11 c48  FAM 30.43074 NA 
12 c48  FAM 30.36933 NA 
13 m72  VIC 29.61585 NA 
14 m72  VIC 28.65742 NA 
15 m72  VIC 29.40057 NA 
16 m72  FAM 32.27304 NA 
17 m72  FAM 32.38696 NA 
18 m72  FAM 32.24386 NA 
19 c72  VIC 28.22370 NA 
20 c72  VIC 28.17342 NA 
21 c72  VIC 28.49104 NA 
22 c72  FAM 31.91751 NA 
23 c72  FAM 31.67524 NA 
24 c72  FAM 31.87287 NA 

它似乎并没有被正确子集划分的数据,我不知道为什么会。我试图用DCT的计算值填充'dCT'列。

+2

你能否用语言什么是你想达到解释?什么是DCT?你为什么运行'DF $ Sample =='sample'',其中'DF $ Sample'中的值不等于'sample'?你想要的输出是什么? – 2015-03-31 10:31:17

+0

如果您查看df,例如在样本'm48'中:DCT = FAM的平均值 - VIC的平均值。我想把这个意思加到'm48'的每一行上。然后,我想重复'c48'等过程。DF $ Sample == sample,其中sample是一个提供给函数的变量,感谢您找到'sample',它应该只是样本而没有任何语言符号。但是仍然没有计算VIC的平均值 - FAM的平均值并附加到df。 – user3062260 2015-03-31 10:43:09

+0

请记得总是发布可复制的数据,例如使用dput或类似的东西。见http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – jhin 2015-03-31 12:09:45

回答

2

下面是使用data.table一个可能的解决方案(假设你没有dCT列)

library(data.table) 
setDT(df)[, dCT := mean(CT[Reporter=='FAM']) - mean(CT[Reporter=='VIC']), by = Sample][] 
# Sample Reporter  CT  dCT 
# 1: m48  VIC 27.50595 3.193127 
# 2: m48  VIC 27.77835 3.193127 
# 3: m48  VIC 27.62321 3.193127 
# 4: m48  FAM 30.87295 3.193127 
# 5: m48  FAM 30.87967 3.193127 
# 6: m48  FAM 30.73427 3.193127 
# 7: c48  VIC 26.56715 3.571867 
# 8: c48  VIC 26.89787 3.571867 
... 
0

同样的事情可以明显dplyr来完成,所以我想我会添加另一个版本。

df <- data.frame(Sample = c(rep("m48", 6), rep("c48", 6)), Reporter = c(rep("VIC", 3), rep("FAM", 3), rep("VIC", 3), rep("FAM", 3)), CT = c(27.50595, 27.77835, 27.62321, 30.87295, 30.87967, 30.73427, 26.56715, 26.89787, 26.82587, 30.20642, 30.43074, 30.36933)) 

library(dplyr) 
df %>% group_by(Sample) %>% 
    mutate(dCT = mean(CT[Reporter == 'FAM']) - mean(CT[Reporter == 'VIC'])) 
# Source: local data frame [12 x 4] 
# Groups: Sample 
# 
# Sample Reporter  CT  dCT 
# 1  m48  VIC 27.50595 3.193127 
# 2  m48  VIC 27.77835 3.193127 
# 3  m48  VIC 27.62321 3.193127 
# 4  m48  FAM 30.87295 3.193127 
# 5  m48  FAM 30.87967 3.193127 
# 6  m48  FAM 30.73427 3.193127 
# 7  c48  VIC 26.56715 3.571867 
# 8  c48  VIC 26.89787 3.571867 
# 9  c48  VIC 26.82587 3.571867 
# 10 c48  FAM 30.20642 3.571867 
# 11 c48  FAM 30.43074 3.571867 
# 12 c48  FAM 30.36933 3.571867 

只是因为我知道它是不是令人满意的接收响应,指出“你做什么不好,宁愿做” - 这里有什么不一起工作的一些注意事项你的原始代码。 但请注意,我仍然推荐其他解决方案之一。

  1. R按值传递函数参数,而不是通过引用。这意味着 ,您不能在函数内部更改数据框df,因为您只处理副本。您宁愿返回 结果,然后使用此结果修改df。
  2. length(dataframe)不会做你认为它所做的事情:它返回的是列数,而不是行数。你想要的是nrow(dataframe)
  3. 为数据框中列的每个元素分配单个consant值不需要循环;只需分配值,R将自动扩展。

所以这里有一个版本的代码,工程:

calc_dCT <- function(sample, DF){ 

    sample_df <- DF[ which(DF$Sample==sample),] 
    VIC <- sample_df[ which(sample_df$Reporter=='VIC'),] 
    FAM <- sample_df[ which(sample_df$Reporter=='FAM'),] 

    VIC_mean<-mean(VIC[,3]) 
    FAM_mean<-mean(FAM[,3]) 

    DCT <- FAM_mean - VIC_mean 

    sample_df$dCT <- DCT 

    sample_df 
} 

dfnew <- data.frame(Sample=character(), Reporter=character(), CT=numeric(), dCT=numeric()) 
for (sample_name in unique(df$Sample)) 
    dfnew <- rbind(dfnew, calc_dCT(sample_name, df))