【问题标题】:Function for sampling between duplicated values in data.frame用于在 data.frame 中的重复值之间进行采样的函数
【发布时间】:2014-04-15 13:00:18
【问题描述】:

所以,我有一个名为“DATA”的 data.frame 对象。 该对象包含一个名为“Point”(DATA$Point) 的列。由于此特定列上有一些重复项,我想构建一个函数,在 DATA 中的这些重复项中仅对一行进行采样。

我一直在尝试这样做:

sort.song<-function(DATA){

 Point<-levels(DATA$Point)
 DATA.NEW<-DATA[1:length(Point),] 

#Ideally DATA.NEW should have an empty dataframe with nrow=length(Point) and the same columns
#as in DATA. But I THINK it will work (I don't know how to do the "ideally" way)

 for(i in 1:dim(DATA)[1]){ #dim(DATA)[1] always bigger than length(Point)
  SUBDATA<-DATA[which(DATA$Point%in%Point[i]),]

#I need to sample one row of the original data set only of the duplicates of the same value.
#So if there isn't a duplicate of one particular value, move on. Otherwise sample one between
#those duplicates.

  l<-dim(SUBDATA)[1]
  if (l==1){DATA.NEW[i,]<-SUBDATA[l,]}else{lc<-sample(1:l,1)}
  DATA.NEW[i,]<-SUBDATA[lc,]
  }
 return(DATA.NEW)
}

test<-sort.song(DATA)

但它不起作用! :( 我收到以下错误消息:

Error in `[<-.factor`(`*tmp*`, iseq, value = integer(0)) : 
replacement has length zero

这可能是一个愚蠢的问题,但我在这里没有选择(完全 R 初学者)

任何帮助将不胜感激!!!!

【问题讨论】:

  • 你想随机抽取重复的样本吗,如果不是这样的话DATA[!duplicated(DATA$Point), ]
  • 是的,我想随机抽样重复(包括重复所基于的值)。我的意思是,函数 duplicated() 只显示重复的值。我想在重复项和重复的值之间进行采样。好的,我可能会感到困惑,因为我是 R 的新手。

标签: r function dataframe sample duplicate-data


【解决方案1】:

如果你想选择一个随机的副本来保留,而不是duplicateds 默认行为只保留第一个,那么为什么不随机打乱整个数据集,这样在打乱的集合中选择第一个实际上是随机的原始行:

DATAr <- DATA[sample(1:nrow(DATA),]
DATAr <- DATAr[!duplicated(DATAr$Point),]

如果您的原始 DATA 的顺序很重要,请将 sample(...) 存储在一个变量中,使用该变量重新排序您的数据,并在删除重复项后应用逆序(或添加列 DATA$ind &lt;- 1:nrow(DATA) 和对您的数据进行排序以在之后恢复。

【讨论】:

  • 它似乎工作,但我不明白为什么它工作,嘿嘿嘿。第一个字符串命令是对所有行进行采样,而不会丢失原始数据集中的任何行?我看到 sample 的默认值是 replace=FALSE,所以不会有任何重复的行,对吗?然后,在第二个字符串命令中,您只用那些注意重复的 DATAr 行覆盖对象 DATAr!?底线:使用这 2 个字符串,我创建了一个新的 data.frame,其中所有原始行都没有重复?
  • sample(1:nrow(DATA)) 将创建行号的重新排列。 replace 这里的概念与duplicate 并不完全相同。如果我有 5 行,那么我的版本可以生成 5,4,3,2,1,而 replace=TRUE 版本可以生成 1,1,5,5,5。前者将(偶然)反转您的行,因此在这种情况下会导致最终的副本被保留;后者 replace=TRUE 会创建第 1 行和第 5 行的人为重复 - 非常 不好的事情,所以默认是正确的选项。你的总结是正确的。
  • 太棒了。感谢您的关注!
  • 不错的解决方案。快速提示:如果数据量很大,对所有数据进行采样可能会占用计算时间。只打乱索引并从那里采样会更有效
【解决方案2】:

R 具有内置函数sampleduplicated。因此,您可以简单地使用

DATA[ sample( !duplicated(DATA$Point), N ), ]
# where `N` is the sample size you'd like. 

在 data.table 语法中,上面是

DATA[ sample( !duplicated(Point), N )]

【讨论】:

  • 我的问题不够清楚。使用 !duplicated 只会给出那些不重复的,对吧?我只想对重复的进行采样。我在原始问题上提供了一些附加信息。
  • 你可以去掉刘海(!)。如果您想要所有这些行,请使用sample(DATA$Point %in% DATA$Point[duplicated(DATA$Point)])
【解决方案3】:

所以你想要每一行不重复的行和那些重复的第一个实例对吗?

然后试试这个:

# build fake dataset
DATA <- as.data.frame(cbind(sample(c(1:10,3:7)),sample(1:15),sample(1:15)))
names(DATA) <- c("Point","some_col","some_other_col")

# check
print(DATA) # See Point has duplicate values


# your function
filter_data <- function(DATA){
distinct_points <- unique(DATA$Point)
as.data.frame(t(sapply(distinct_points, function(x){subset(DATA,Point == x)[1,]})))
}


#result
DATA.new <- filter_data(DATA)
print(DATA.new)

【讨论】:

  • 你能解释一下这个字符串命令是什么意思吗? as.data.frame(t(sapply(distinct_points, function(x){subset(DATA,Point == x)[1,]}))) }
  • sapply 一个接一个地获取所有不同的点,并使用该值获取 DATA 的第一行,它返回一个矩阵,我必须转置该矩阵才能将其恢复为初始格式,然后转换回数据帧。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-14
  • 2013-11-06
  • 1970-01-01
  • 1970-01-01
  • 2015-04-22
  • 2021-06-14
  • 2015-07-01
相关资源
最近更新 更多