【问题标题】:Subset non 0 values in a data.frame [duplicate]在data.frame中子集非0值[重复]
【发布时间】:2013-09-11 12:36:41
【问题描述】:

我有一个如下所示的 data.frame (DF):

 Col_names1      Col_values1    Col_names2     Col_values2    
     a                98             f               1           
     b                12             h              0.8         
     d                 0             mn              0            
     e               0.12            p               0                 
    ....             ....           ....            ....

我必须逐行列出每个 Col_names 列中 Col_names 的频率。为此,我首先仅提取名称以具有以下 new_DF

 Col_names1       Col_names2     
     a                f                
     b                h                 
     d                mn                  
     e                p                    
    ....             ....           

然后我使用apply函数逐行列出名字的频率:

apl = apply(new_DF, 1, table)

问题在于,即使(例如“d”)初始 DF 中的相关数值为“0”时,它也给了我名称的频率。该频率不必计算。

PS:data.frame 总共有 500 列和 80 行。

【问题讨论】:

  • 当“Col_values2”在该行中为零时,为什么会返回“e”行?
  • 因为项目根据列是独立的。换句话说,在 Col_names2 中,与“e”对应的项目是“p”,具有“0”值,因此将其删除。 Col_names1 列中的项目“e”的值为 0.12,因此无需将其删除..
  • @Fuv8,那么您希望它如何工作呢? data.frames 是矩形数据结构。
  • 我不知道 Ananda Mahto...我只知道我必须删除这些项目..

标签: r


【解决方案1】:

这种方法对你有用吗?

set.seed(1)
example <- data.frame(col_names1=sample(letters[1:13],30,replace=TRUE),
                      col_values1=sample(0:10,30,replace=TRUE),
                      col_names2=sample(letters[14:26],30,replace=TRUE),
                      values2=sample(0:10,30,replace=TRUE))
> dim(example)
[1] 30  4
> head(example)
  col_names1 col_values1 col_names2 values2
1          d           5          y       2
2          e           6          q       0
3          h           5          s       7
4          l           2          r       9
5          c           9          v       8
6          l           7          q       8


new.df <- data.frame(names=unlist(example[,grep("names",colnames(example))]),
                     values=unlist(example[,grep("values",colnames(example))]))

> dim(new.df)
[1] 60  2
> head(new.df)
            names values
col_names11     d      5
col_names12     e      6
col_names13     h      5
col_names14     l      2
col_names15     c      9
col_names16     l      7

然后您可以只删除基于一列的值。

new.df[new.df$values!=0,]

【讨论】:

  • 嗨,戴恩!效果很好,非常感谢。我只需要以适当的方式列出结果,但这不是问题。再次感谢您!
【解决方案2】:

一种选择是使用list(但我认为这种情况下长数据形式可能更方便,而且您的数据不是很大)。

假设您的data.frame 被称为“mydf”:

## Create a matrix to subset each pair of columns
mat <- matrix(1:4, ncol = 2, byrow = TRUE)

## use `lapply` to subset and remove the offensive rows
lapply(sequence(nrow(mat)), function(x) {
  temp <- mydf[mat[x, ]]
  temp[temp[2] != 0, ]
})
# [[1]]
#   Col_names1 Col_values1
# 1          a       98.00
# 2          b       12.00
# 4          e        0.12
# 
# [[2]]
#   Col_names2 Col_values2
# 1          f         1.0
# 2          h         0.8

基于@dayne 的回答,如果您的列以常规模式命名,您可以非常有效地使用reshape 来获得长格式。但是,它需要一个“id”变量(sequence(nrow(DF)) 应该这样做)。

例子:

### Sample data
set.seed(1)
DF <- data.frame(col_names1 = sample(letters[1:13], 30, replace=TRUE),
                 col_values1 = sample(0:10, 30, replace=TRUE),
                 col_names2 = sample(letters[14:26], 30, replace=TRUE),
                 col_values2 = sample(0:10, 30, replace=TRUE))

### Add the ID
DF <- cbind(id = 1:nrow(DF), DF)

### Reshape the data into a long form
out <- reshape(DF, direction = "long", idvar="id", 
               varying = setdiff(names(DF), "id"), sep = "")

### Subset
out2 <- out[out$col_values != 0, ]
head(out2)
#     id time col_names col_values
# 1.1  1    1         d          5
# 2.1  2    1         e          6
# 3.1  3    1         h          5
# 4.1  4    1         l          2
# 5.1  5    1         c          9
# 6.1  6    1         l          7

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-08
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-23
    相关资源
    最近更新 更多