【问题标题】:Select the first new value in a column选择列中的第一个新值
【发布时间】:2015-01-03 00:49:08
【问题描述】:

我有一个包含 351080 个观察值的数据集,(转置)如下所示:

Subject     1 1 1 2 2 3 3 3 3  
nationality G G G D D S S S S  

与:

table(dat$Nationality)

R 只返回观察的总数。如何告诉 R 只选择每个主题的国籍一次?

【问题讨论】:

  • 嘘!有一个专门用于数据科学的 datascience.stackexchange.com 站点。也许你可能会在那里得到更好的帮助......关于表格列格式,人们通常使用代码块(在帖子编辑器中使用 {} 按钮,或 CTRL + K 在选定的文本上)。
  • 澄清您所说的“选择每个主题的国籍一次”的意思。你想要的输出是什么样的?
  • 谢谢。下次我会记住的:)。 table(dat$nationality) 之后的数据过去看起来像这样(我将使用上面的“数据”进行说明) G 3 D 2 S 4 但我希望它是:G 1 D 2 S 3 因为那里只有一个G人,一个D人,一个S人

标签: r unique


【解决方案1】:

构造数据:

dat <- data.frame(Subject = rep(1:3, each=3),
                  Nationality = rep(c("G","D","S"), each=3))

试试这个:

with(dat,table(tapply(as.character(Nationality),
                      list(Subject),head,n=1)))
## D G S 
## 1 1 1 
  • with() 在数据框的上下文中查找,以避免一直输入 dat$
  • tapply() 对由组 (list(Subject)) 分隔的向量 (Nationality) 的每个元素运行指定的函数 (head),并带有可选参数 (n=1 仅采用第一个元素)。
  • as.character() 很难看,但会阻止 R 将因子转换为数字代码。
  • table 计算表格。

你也可以试试这个:

library("dplyr")
d2 <- dat %>% group_by(Subject) %>%
              summarise(Nationality=head(Nationality,1))
table(d2$Nationality)

测试速度:

n <- 351078 ## divisible by 3, for convenience
set.seed(101)
nat <- sample(c("G","D","S"),size=n/3,replace=TRUE)
dat <- data.frame(Subject = rep(1:(n/3),each=3),
                  Nationality = rep(nat,each=3))
system.time(tab <- with(dat,table(tapply(as.character(Nationality),
                      list(Subject),head,n=1))))

这在我的机器上大约需要 1.9 秒 ...

另一方面

 system.time(tab2 <- with(dat,table(Nationality[!duplicated(Subject)])))

大约需要 0.02 (!) 秒 ...

【讨论】:

  • 哇,你们好快,非常感谢!刚刚试过:'with(dat,table(tapply(as.character(Nationality), list(Subject),head,n=1)))' 它有效!非常感谢!
猜你喜欢
  • 2015-10-15
  • 1970-01-01
  • 1970-01-01
  • 2014-11-11
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多