【问题标题】:Subsetting cluster-specific values across a list of data.frames in R在 R 中的 data.frames 列表中设置特定于集群的值
【发布时间】:2020-03-07 11:14:24
【问题描述】:

this answer 的启发,我的目标是在m 的data.frames 集群中找到仅特定于一个m(例如m[[15]])而不是其他ms 的变量。

例如,我知道变量genre == 4 仅特定于m[[15]](“Fazio”即names(m)[15]),而genre == 4 不会出现在任何其他m 集群中(由@ 确认987654331@).

因此,我希望我的输出给我命名 "Fazio"genre == 4

我想对mods 中显示的所有变量重复此过程,而不仅仅是genre

我尝试了以下方法但没有成功:

d <- read.csv("https://raw.githubusercontent.com/rnorouzian/m/master/v.csv", h = T) # DATA

mods <- c("genre","cont.type","time","cf.timely","ssci","setting","ed.level",  # mods
          "Age","profic","motivation","Ss.aware","random.grp","equiv.grp",
          "rel.inter","rel.intra","sourced","timed","Location",
          "cf.scope","cf.type","error.key","cf.provider","cf.revision","cf.oral",
          "Length","instruction","graded","acc.measure","cf.training","error.type")

m <- split(d, d$study.name) # `m` clusters of data.frames

# SOLUTION TRIED:

tmp = do.call(rbind, lapply(mods, function(x){
  d = unique(d[c("study.name", x)])
  names(d) = c("study.name", "val")
  transform(d, nm = x)
}))

# this logic may need to change:
tmp = tmp[ave(as.numeric(as.factor(tmp$val)), tmp$val, FUN = length) == 1,] 

lapply(split(tmp, tmp$study.name), function(a){
 setNames(a$val, a$nm)
})                               # doesn't return anything

【问题讨论】:

  • 是否需要按mod分组,即tmp[with(tmp, ave(val, val, nm, FUN = length)==1),]
  • 逻辑是根据'val'和'nm'即mods列过滤'val'中唯一元素长度为1的行
  • 但这只是分成列表,而你想要别的东西? tmp1 &lt;- tmp[with(tmp, ave(val, val, nm, FUN = length)==1),]; split(tmp1, tmp1$study.name, drop = TRUE)

标签: r list function loops dataframe


【解决方案1】:

我们也可以通过在ave 中添加“nm”来进行分组

tmp1 <- tmp[with(tmp, ave(val, val, nm, FUN = length)==1),]

现在执行split

tmp2 <- lapply(split(tmp1, tmp1$study.name, drop = TRUE), `row.names<-`, NULL)
rm.df <- data.frame(study.name = c(rep("Bitc_Knch_c", 3),
  rep("Sun", 3)), code = c(88,88,88,7,4,0), 

 mod.name = c("error.type","cf.scope","cf.type","error.type",
     "cf.type","error.key"))
rm.these <- split(rm.df, rm.df$study.name)

tmp2[names(rm.these)] <- Map(function(x, y) {
     subset(x, !(nm %in% y$mod.name & val %in% y$code))}, 
     tmp2[names(rm.these)], rm.these)
Filter(nrow, tmp2)

【讨论】:

  • @Reza 1) 很高兴帮助,2) drop = TRUE 是删除 NULL 列表元素。如果您不这样做,那么将获得所有组合(正如我所了解的那样),3)是的,只需执行lapply(split(tmp1, tmp1$study.name, drop = TRUE), 'row.names&lt;-', NULL)
  • @Reza 可能会有所帮助tmp2 &lt;- lapply(split(tmp1, tmp1$study.name, drop = TRUE), 'row.names&lt;-', NULL); tmp2[names(rm.these)] &lt;- Map(function(x, y) {y1 &lt;- stack(y); subset(x, !(nm %in% y1$ind &amp; val %in% y1$values))}, tmp2[names(rm.these)], rm.these); Filter(nrow, tmp2)
  • @rnorouzian 是的,这就是 subset 的部分,我们 stack 'rm.these` 的 list 中的命名向量并删除那些特定元素。如果您检查tmp2[names(rm.these)],这里我们将替换 'tmp2
  • Arun,我们能否从您上面的答案中的tmp1 中删除以下 data.frame:rm.df &lt;- data.frame(study.name = c(rep("Bitc_Knch_c", 3), rep("Sun", 3)), code = c(88,88,88,7,4,0), mod.name = c("error.type","cf.scope","cf.type","error.type","cf.type","error.key"))
  • @Reza 如果您检查代码,我将rm.df 拆分为study.name,并比较要删除的相应“study.name”元素
猜你喜欢
  • 2019-12-16
  • 2019-09-29
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 2020-06-09
  • 1970-01-01
  • 1970-01-01
  • 2016-04-19
相关资源
最近更新 更多