首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于现有列和位于其旁边的列的新列

基于现有列和位于其旁边的列的新列
EN

Stack Overflow用户
提问于 2017-08-18 23:12:44
回答 4查看 151关注 0票数 3

我的数据帧如下所示

代码语言:javascript
复制
ID t1 obs1 t2 obs2 t3 obs3
1  0  a    11 d    0  g
2  0  b    13 e    11 i
3  0  c    0  f    0  h

我需要确保每个ID至少有一个大于10的t(如果没有,则删除行)。然后,我希望保存大于10的最低t值,但也要将相应的ob保存在新列中。(关于我的问题的复杂部分是,10以上的最低t可以在任何列中)。对应于某个t的obs位于下一列中,因此这很有帮助。因此,我得到的数据框将如下所示:

代码语言:javascript
复制
ID t1 obs1 t2 obs2 t3 obs3 lowesttabove10 correspondingobs
1  0  a    11 d    0  g    11             d
2  0  b    13 e    11 i    11             i
EN

回答 4

Stack Overflow用户

发布于 2017-08-19 00:29:04

使用data.table时,请转到长格式:

代码语言:javascript
复制
library(data.table)
setDT(DT)
dat = melt(DT, measure.vars = patterns("^t\\d+$", "^obs\\d+$"), value.name = c("t", "obs"))
setorder(dat, ID, variable)

#    ID variable  t obs
# 1:  1        1  0   a
# 2:  1        2 11   d
# 3:  1        3  0   g
# 4:  2        1  0   b
# 5:  2        2 13   e
# 6:  2        3 11   i
# 7:  3        1  0   c
# 8:  3        2  0   f
# 9:  3        3  0   h

查找每个组的最大值,并标记要保留的组:

代码语言:javascript
复制
IDDT = dat[order(-t), 
  .(max.variable = first(variable), max.t = first(t), max.obs = first(obs))
, by=ID]
IDDT[, keep := max.t > 10]

#    ID max.variable max.t max.obs  keep
# 1:  2            2    13       e  TRUE
# 2:  1            2    11       d  TRUE
# 3:  3            1     0       c FALSE

使用滚动update join查找每个保留组的最小值超过10:

代码语言:javascript
复制
IDDT[(keep), c("my.variable", "my.t", "my.obs") := {
  m = .(ID = ID, t_thresh = 10)
  dat[m, on=.(ID, t = t_thresh), roll=-Inf, .(x.variable, x.t, x.obs)]
}]

#    ID max.variable max.t max.obs  keep my.variable my.t my.obs
# 1:  2            2    13       e  TRUE           3   11      i
# 2:  1            2    11       d  TRUE           2   11      d
# 3:  3            1     0       c FALSE          NA   NA     NA

到此为止,主要数据采用长格式datID级别的变量位于单独的表IDDT中。要将dat过滤到应该保留的组中:dat[IDDT[(keep), .(ID)], on=.(ID)]。有关语法的详细信息,请参阅加载包时提到的?data.table和其他介绍材料。

如果您坚持要返回wide,请参阅?dcast

票数 4
EN

Stack Overflow用户

发布于 2017-08-19 00:25:49

使用基数R:

删除t值不大于10的所有行:

代码语言:javascript
复制
df1 <- df1[rowSums(df1[, grepl("^t", colnames(df1))] >10) > 0, ]

确定包含大于10的最低值的组,然后检索值:

代码语言:javascript
复制
df1$group <- apply(df1[grepl("^t", names(df1))], 1, function(x) which(x == min(x[x > 10])))
df1 <- cbind(df1, do.call(rbind, lapply(seq_len(nrow(df1)), 
                                        function(x) setNames(df1[x, paste0(c("t", "obs"), df1$group[x])],
                                                             c("lowesttabove10", "correspondingobs")))))

> df1
  ID t1 obs1 t2 obs2 t3 obs3 group lowesttabove10 correspondingobs
1  1  0    a 11    d  0    g     2             11                d
2  2  0    b 13    e 11    i     3             11                i
票数 3
EN

Stack Overflow用户

发布于 2017-08-18 23:57:40

我的方法不是很好,但仍然有效,你可以试一试。

代码语言:javascript
复制
library(dplyr)
library(reshape)
df1=melt(df,id='ID')

df2=df1%>%group_by(ID)%>%filter(value>10)%>%dplyr::slice(which.min(value))%>%na.omit()

> df2
# A tibble: 2 x 3
# Groups:   ID [2]
     ID variable value
  <int>   <fctr> <chr>
1     1       t2    11
2     2       t3    11


df2$variable=as.character(df2$variable)
C=as.numeric(gsub("[[:alpha:]]", "", df2$variable))
df=df[df$ID%in%df2$ID,]
for (i in 1:length(C)){
DF1=df[i,str_detect(names(df),as.character(C[i]))]
names(DF1)=c('lowesttabove10 ','correspondingobs')
if (i ==1 ){DFF=DF1}else{DFF=rbind(DFF,DF1)}
}
cbind(df,DFF)

  ID t1 obs1 t2 obs2 t3 obs3 lowesttabove10  correspondingobs
1  1  0    a 11    d  0    g              11                d
2  2  0    b 13    e 11    i              11                i
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45759919

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档