【问题标题】:Assess each row of a factor in R评估 R 中因子的每一行
【发布时间】:2014-11-02 07:18:38
【问题描述】:

我有一个包含 1000 行和 848 个级别的因子(即有些行是空的)。对于每一行,我想计算元素的数量(即一个元素 = 1、2 个元素 = 2、空行 = 0 等)。一种更简单的描述方式是:我想将一个因子转换为 data.frame,但我想将数据类型从因子更改为数字并保留每一行中的值。

v.m.two <- Output[,1]
v.m.two <- data.frame(v.m.two)
class(v.m.two)
[1] data.frame
class(v.m.two[1,]
[1] factor
dim(v.m.two)
[1] 1000 1
v.m.two[1,]
[1] 848 Levels: 0 1000 1002, 4875, 4082, 1952 1015, 2570, 3524 1017 1020, 1576 ... 983, 4381,
2256, 4361, 4271

有什么建议吗?

           v.m.two
1       2633, 4868
2        126, 4860
3                0
4        122, 4762
5             4256
6 2933, 2892, 2389

基本上,我想计算每一行中的值(例如,第 1 行是 2,第 2 行是 2,第 3 行是 0,等等)。

【问题讨论】:

  • 你能显示几行v.m.two吗?您可能还想使用v.m.two &lt;- data.frame(v.m.two, stringsAsFactors = FALSE)
  • “计算元素个数”是什么意思?每行只有一个值。你只想要as.numeric(as.character(v.m.two[, 1]))吗?
  • 嘿,理查德,我在原始帖子中进行了编辑。我已经尝试过了,但它并没有按照预期的方式工作。我不确定为什么>.>
  • 好吧,也许你想要sapply(strsplit(as.character(v.m.two[, 1]), ','), length)
  • 嘿 jbaums,因为数据类型是一个因素,所以你是正确的,因为每一行都包含一个值。但在每一行中,都包含一个由“,”分隔的元素列表,我想计算这些值。

标签: r


【解决方案1】:

您有错误的逗号导致这些因素。试试scan

scan(text=with(v.m.two, levels(v.m.two)[v.m.two]), sep=",", what=integer())
# Read 11 items
# [1] 2633 4868  126 4860    0  122 4762 4256 2933 2892 2389

并且要计算长度并转换为数字,您还可以使用strsplit

s <- strsplit(as.character(v.m.two[[1]]), ", ")
vapply(s, length, integer(1L)) ## row 3 is actually 1 if there's a zero there
# [1] 2 2 1 2 1 3
as.numeric(do.call(c, s))
# [1] 2633 4868  126 4860    0  122 4762 4256 2933 2892 2389

【讨论】:

  • 我收到此错误:扫描错误(文件,内容,nmax,sep,dec,quote,skip,nlines,na.strings,:scan() 预期为'一个整数',得到'2633 ,'
  • 因为我用的是空格而不是逗号,即将修复
【解决方案2】:

1 将因子转换为数值

  • 如果您想将factor 列转换为numeric 并希望根据每行中的元素数来分隔列。

     library(splitstackshape)
     res <- cSplit(v.m.two, 'v.m.two', sep=",")
     res
     #    v.m.two_1 v.m.two_2 v.m.two_3
     #1:      2633      4868        NA
     #2:       126      4860        NA
     #3:         0        NA        NA
     #4:       122      4762        NA
     #5:      4256        NA        NA
     #6:      2933      2892      2389
    
      str(res)
      #Classes ‘data.table’ and 'data.frame':   6 obs. of  3 variables:
      #$ v.m.two_1: int  2633 126 0 122 4256 2933
      # $ v.m.two_2: int  4868 4860 NA 4762 NA 2892
      #$ v.m.two_3: int  NA NA NA NA NA 2389
    
  • 如果你需要vector,你可以使用stri_split from stringi

      library(stringi)
      as.numeric(unlist(stri_split(v.m.two[,1], regex=",")))
      #[1] 2633 4868  126 4860    0  122 4762 4256 2933 2892 2389
    

2。计算行中的值

  • 要计算v.m.two 的每一行中的值,您可以从上面的resv.m.two 进行计数。在第一个选项中,我们计算res 的每一行中NAs 的数量,然后乘以从v.m.two 的第一列是否为0 得出的逻辑索引。 TRUE 值即!=0 将得到countFALSE 将强制转换为0 即。 0 * value=0

      (v.m.two[,1]!=0)*(rowSums(!is.na(res)))
      #[1] 2 2 0 2 1 3    
    
  • 您可以使用stringi 中的stri_count,这会很快 (counting occurrence of particular letter in vector of words in r)。如上所述,您可以使用arithmetic,即乘法,也可以使用ifelseregex 可以基于digits,。如果您使用的是,,请务必添加1

      ifelse(v.m.two[,1]=0, stri_count(v.m.two[,1], regex="\\d+"), 0)
      # [1] 2 2 0 2 1 3
      #Or
    
      (v.m.two[,1]!=0) *stri_count(v.m.two[,1], regex="\\d+")
      #[1] 2 2 0 2 1 3
      #Or   
      (v.m.two[,1]!=0) *(stri_count(v.m.two[,1], regex=",") +1)
      #[1] 2 2 0 2 1 3
    
  • 另一个计数选项是使用base R 中的gsubnchar

      (v.m.two[,1]!=0) *( nchar(gsub("[^,]", "", v.m.two[,1]))+1)
      #[1] 2 2 0 2 1 3
    

数据

v.m.two <- structure(list(v.m.two = structure(c(4L, 3L, 1L, 2L, 6L, 5L), 
.Label = c("0", "122, 4762", "126, 4860", "2633, 4868", "2933, 2892, 2389",
 "4256"), class = "factor")), .Names = "v.m.two", row.names = c("1", 
"2", "3", "4", "5", "6"), class = "data.frame")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 2014-01-28
    • 2021-07-23
    相关资源
    最近更新 更多