【问题标题】:Issue with tapplytapply 的问题
【发布时间】:2019-07-24 22:39:21
【问题描述】:

我正在使用 tapply 按样本 ID(SID) 组合表格。对于列表中的第一个样本,有 3 个测量值,但它仅显示为一个。

我有 4 件事需要传递到新表。首先是 SID。其次是具有该 SID 的所有测量值的面积平均值。第三是所有的距离。最后是测量次数。

cases_iTLS <- data.frame(unique(iTLS$SID))
colnames(cases_iTLS)[colnames(cases_iTLS)=="unique.iTLS.SID."] <- "SID"
cases_iTLS$SID <- factor(cases_iTLS$SID)

# Average of TLS on one slide for area
cases_iTLS$Area_iTLS <- tapply(iTLS$Area, iTLS$SID,FUN=mean) 

# Average of TLS on one slide for distance
cases_iTLS$Distance_iTLS <- tapply(iTLS$Distance, iTLS$SID,FUN=mean) 

# Number of measurements per SID
cases_iTLS$Count_iTLS <- tapply(iTLS$Region_Index, iTLS$SID,FUN=length) 


SID       Region_index   Area         Distance    Type    Location
112906    1              53531.53     71.982      iTLS    intratumoral
112906    3              76809.61     97.384      iTLS    intratumoral
112906    5              40937.30     9.643       iTLS    intratumoral
112947    1              35071.66     2.067       iTLS    intratumoral
112947    3              17979.88     36.319      iTLS

【问题讨论】:

  • 您的问题是什么?您的代码有什么错误或不良结果?
  • 第一个样本的输出是 Count_iTLS = 1。但在输入中有 3 行具有唯一的 Region_index。所需的输出应该是 Count_iTLS=3。此外,另外两个 tapply 给出的方法不正确。
  • 没有结构和数据的例子很难回答。由于使用或不使用 NA ,平均值是错误的吗? :How to pass na.rm as argument to tapply?
  • @phili_b 我已将数据结构添加到主要问题中。数据中没有不适用的单元格
  • dput(myvariable) 放在这里结构会更容易测试:)

标签: r


【解决方案1】:

因为您需要跨多个列(AreaDistanceSID 运行单独的聚合函数(meanlength) >),考虑使用aggregate进行分组聚合返回一个数据框。

通常,tapply 在单个数字指标上运行,而不是跨列或函数返回单个命名的原子向量。下面调用一个do.call+data.frame来绑定多个聚合的嵌套结果

aggregate

# AGGREGATE ACROSS COLS AND FUNCS
cases_iTLS <- aggregate(cbind(Area, Distance, Region_Index) ~ SID, iTLS, 
                        function(x) c(mean=mean(x), count = length(x))

# BIND NESTED, UNDERLYING RESULTS
cases_iTLS <- do.call(data.frame, cases_iTLS)

# KEEP NEEDED COLUMNS
cases_iTL <- cases_iTL[c("SID", "Area.mean", "Distance.mean", "Region_Index.count")

tapply

如果您想走tapply 路线,请考虑使用rbind 构建您的单独聚合矩阵并转置t

cases_iTL_mat <- with(iTLS, 
                         t(rbind(Area_mean = tapply(Area, SID, FUN=mean) ,
                                 Distance_mean = tapply(Distance, SID, FUN=mean),
                                 Region_count = tapply(Region_Index, SID, FUN=length)
                          ))
                 )

by

如果我没有指出bytapply 的面向对象的包装器),我会失职:

cases_iTL_mat <- do.call(rbind, 
        by(iTLS, iTLS$SID, function(sub) {
               c(Area_mean = mean(sub$Area),
                 Distance_mean = mean(sub$Distance),
                 Region_count = length(sub$Region_Index))
          })
)

【讨论】:

  • 这似乎有效。我只是对“保留需要的列”部分有疑问。我需要使用这些名称来调用函数还是只是重命名列
  • 期间限定名称源自对列的聚合调用,但可以在之后或在 c() 函数中重命名。具体来说,在aggregate 内部,c(Andre_func = mean(x)) 最后呈现为Area.Andre_func
猜你喜欢
  • 2013-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-29
  • 2011-09-11
相关资源
最近更新 更多