0

我有一个如下所示的 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 行。

4

2 回答 2

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,]
于 2013-09-11T13:02:59.363 回答
1

一种选择是使用a 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
于 2013-09-11T13:13:01.483 回答