【问题标题】:tapply - creating NA?tapply - 创建 NA?
【发布时间】:2013-07-18 16:26:43
【问题描述】:

我正在尝试计算每人独特水果的平均数量(我通常的实践数据)。这对这两行代码都非常有效:

with(df, tapply(fruit, names, FUN = function(x) length(unique(x))))->uniques
sum(uniques)/length(unique(df$names))

aggregate(df[,"fruit"], by=list(id=names), FUN = function(x) length(unique(x)))->d1
sum(d1$x)/length(unique(df$names))

我的问题是,当我在真实数据上使用代码时,它不起作用。我的真实数据是处方数据,我想要平均每人独特药物的数量。使用 tapply 代码,它似乎创建了原始 df 中不存在的全新患者 ID。它还返回了 1000 个 NA 值。我的 id 列中没有缺失值,drug_code 列中也没有缺失值

with(dt3, tapply(drug_code, id, FUN = function(x) length(unique(x))))->uniques    

head(uniques)
                   uniques
Patient HAI0000001      NA
Patient HAI0000003      NA
Patient HAI0000008      NA
Patient HAI0000010      NA
Patient HAI0000014      NA
Patient HAI0000020      NA

table(dt3$id=="Patient HAI0000001")  ##checking to see if HA10000001 occurs in original df. the dim of df are 228954 rows and 5 cols

FALSE 
228954

对于聚合代码,我得到一个错误:

aggregate(dt3[,"drug_code"], by=list(id=id), FUN = function(x) length(unique(x)))->d1

Error in aggregate.data.frame(as.data.frame(x), ...) : 
  arguments must have same length

我不明白发生了什么。我的真实数据与我的实践数据相似,因为它有一个 id col 并有一个 drug/fruit 列。两个df中都没有丢失数据。我知道 lapply 更适合数据帧,但我不一定需要 df 返回。在任何情况下,tapply 代码都适用于 df 的练习数据。有谁知道这里发生了什么?

练习 DF:

 names<-as.character(c("john", "john", "john", "john", "john", "mary", "mary","mary","mary","mary", "jim", "sylvia","ted","ted","mary", "sylvia", "jim", "ted", "john", "ted"))
dates<-as.Date(c("2010-07-01",  "2010-09-01", "2010-11-01", "2010-12-01", "2011-01-01", "2010-08-12",  "2010-11-11", "2010-05-12",  "2010-12-03", "2010-07-12",  "2010-12-21", "2010-02-18",  "2010-10-29", "2010-08-13",  "2010-11-11", "2010-05-12",  "2010-04-01", "2010-05-06",  "2010-09-28", "2010-11-28" ))
fruit<-as.character(c("kiwi","apple","banana","orange","apple","orange","apple","orange", "apple", "apple", "pineapple", "peach", "nectarine", "grape", "melon", "apricot", "plum", "lychee", "watermelon", "apple" ))
df<-data.frame(names,dates,fruit) 

真实数据示例:

head(dt3)
        id         quantity   date_of_claim drug_code  index
1  Patient HAI0000560        1    2009-10-15 R03AC02 2010-04-06
2  Patient HAI0000560        1    2009-10-15 R03AK06 2010-04-06
3  Patient HAI0000560       30    2009-10-15 R03BB04 2010-04-06
4  Patient HAI0000560       30    2009-10-15 A02BC01 2010-04-06
5  Patient HAI0000560       50    2009-10-15 M02AA15 2010-04-06
6  Patient HAI0000560       30    2009-10-15 N02BE51 2010-04-06

【问题讨论】:

    标签: r plyr tapply


    【解决方案1】:

    在您的情况下,您要询问一个数字:患者 ID 内特定向量 (unique(fruits)) 的所有单独长度的平均值。这首先向您展示了个人唯一计数,然后是平均函数结果:

    > with(df,  tapply(fruit, names, function(x) length(unique(x)) ))
       jim   john   mary sylvia    ted 
         2      5      3      2      4 
    > mean ( with(df,  tapply(fruit, names, function(x) length(unique(x)) )) )
    [1] 3.2
    

    我想说的是,您在上面的代码中对包含特定值的测试有一个尾随空格,这可能会导致问题。 "string " 不等于 "string"。我已经在我的 .Rprofile 文件中的pkg::gdata 中放置了使用修剪功能的副本,以便我更容易处理这种可能性。

    【讨论】:

    • 您好 Dwin,感谢您的回复。尾随空格只是我在传输代码时的一个错误,它不是问题的原因。使用平均函数比我所做的要好——但这不是问题。问题是轻拍。它在不应该出现的地方创建了所有这些 Nas。它适用于虚拟数据,我无法弄清楚为什么它不适用于真实数据。 dummydata 等于真实数据,因为 tapply 代码中的所有变量都是因子变量。实际数据中没有 Nas,所以我不知道为什么 tapply 制造它们。
    • 等等——我想我已经想通了——敬请期待
    • 如果您发帖dput(head(dt3)),我们可以提供更好的帮助。
    • 好的,这就是答案!我通过从另一个更大的父 DF 切割它来制作我真正的 DF (dt3)。因此,dt3 中的 id 级别保持与父 DF 相同。这就是所有 Nas 的来源。解决方案很简单............ sum(x, na.rm=TRUE)/length(unique(dt3$hai_dispense_number))。我坚持这一点 - mean(x, na.rm=TRUE) 需要太长时间!感谢您的帮助!
    • 再次感谢 DWin - 当我将 dput 放到这里时,解决方案更加明显。
    【解决方案2】:

    我可能遗漏了一些东西,但一个简单的tapply 不能在这里工作吗?下面一行计算了每人不同水果的数量

    x=tapply(df$fruit,df$names,function(x){length(unique(x))})
    

    然后mean(x) 会给你每个人的平均值?

    【讨论】:

    • 嗨 slammaster - 感谢您的回复。看我对 Dwin 的回复,平均函数不是我的问题——问题是指为什么 tapply 在我的真实 df 中创建 Nas。无法弄清楚为什么会这样。
    • 您好 slammaster - 我想通了 - 请参阅我在与 DWin 的对话中提出的解决方案。有趣的是,平均值(x,na.rm=TRUE)运行时间太长,所以我坚持使用总和/长度。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多