【问题标题】:Extracting a series of integers using a loop使用循环提取一系列整数
【发布时间】:2016-02-23 16:27:43
【问题描述】:

我有一些数据要提取整数出现的频率。以下是一些示例数据:

df <- read.table(header=T, text="A B C D 
1          1         5          3         1  
2          1         2          3         2  
3          2         3          5         3  
4          1         4          5         3  
5          3         1          4         2  
6          5         2          5         1 
") 
df

我可以遍历这些并得到如下计数:

for (i in 1:5){ 
 print(colSums(df==i))
}

但每次我尝试存储输出时都会出错。将结果输出存储在数据框中的最简洁方法是什么?我想我对存储循环运行的数据的方式感到困惑。谢谢你的帮助。

【问题讨论】:

  • 根据这个输入你想要的输出是什么?大多数时候,for循环不是要走的路。你是如何存储输出的?
  • @Heroka OP 已经显示了所需的输出
  • 对于每个列标题,我希望能够清楚地看到有多少次 1s、2s 等。

标签: r loops multiple-columns


【解决方案1】:

我们可以使用mtabulate

library(qdapTools)
t(mtabulate(df))
#  A B C D
#1 3 1 0 2
#2 1 2 0 2
#3 1 1 2 2
#4 0 1 1 0
#5 1 1 3 0

base R中,我们还可以unlist数据集,复制列名,并使用table(不使用任何循环,显式(for)或隐式(lapply)。

table(unlist(df),names(df)[col(df)])
#   A B C D
# 1 3 1 0 2
# 2 1 2 0 2
# 3 1 1 2 2
# 4 0 1 1 0
# 5 1 1 3 0

或者正如@nicola 提到的,我们可以使用rep 代替col(df)(应该更快)

table(unlist(df), rep(names(df),each=nrow(df)))

【讨论】:

  • 很好的解决方案。在base 中,我更喜欢rep(names(df),each=nrow(df))(而不是names(df)[col(df)]),但我知道你非常喜欢rowcol :)
  • @nicola 感谢您的反馈。我认为rep 应该更快。
【解决方案2】:

我们也可以在没有 for 循环的情况下在 base-R 中执行此操作:

do.call(cbind, lapply(df, function(x){table(factor(x,levels=1:6))}))

  A B C D
1 3 1 0 2
2 1 2 0 2
3 1 1 2 2
4 0 1 1 0
5 1 1 3 0
6 0 0 0 0

【讨论】:

  • +1 但是,如您所知, lapply 是循环的包装器。所以我不确定我是否会称之为没有循环的解决方案。但是你说得对,没有for 循环;-)
  • 我知道。但对我来说,lapply(df, ...for(i in 1:ncol(df)) 优雅得多。 R 的乐趣,100 种实现相同结果的方法 :)
  • 我同意。 lapply 更好。
  • 我认为水平应该是1:5(6是帖子中的行号)
  • 你是对的。但是,在问题的早期版本中是1:6,所以我认为这是可能出现的数字。
【解决方案3】:

这是另一个选择:

library(reshape2)
table(melt(df))
#No id variables; using all as measure variables
#        value
#variable 1 2 3 4 5
#       A 3 1 1 0 1
#       B 1 2 1 1 1
#       C 0 0 2 1 3
#       D 2 2 2 0 0

【讨论】:

    【解决方案4】:

    与@akrun 不同,我更喜欢尽可能使用base R。

    out <- matrix(0, nrow= 6, ncol=4, dimnames= list(1:6, LETTERS[1:4]))
    for (i in 1:6) {
      out[i,] <- unlist(lapply(df, function(j) sum(j == i)))
    }
    
    R> out
      A B C D
    1 3 1 0 2
    2 1 2 0 2
    3 1 1 2 2
    4 0 1 1 0
    5 1 1 3 0
    6 0 0 0 0
    

    【讨论】:

    • 所以我认为您的回答解决了我的困惑。我需要在 j 中使用单独的索引,我想我在尝试中两次使用 i 作为索引。非常感谢。
    • 我同意base-R。但是,在这种情况下,为什么不使用 table 而不是 for 循环呢?
    • @Heroka 我个人偏好尽可能使用与语言无关的工具。这与使用基本 R 的哲学相似......是的,我认识到这不是一个纯粹的语言不可知论解决方案(lapplyunlist),但这些只是数据结构构造
    • 请注意,如果我复制并粘贴 @Alex 的回复,我会收到错误 Error in out[i, ] &lt;- unlist(lapply(df, function(j) sum(j == i))) : object 'out' not found
    • 我认为是复制粘贴错误,我将矩阵赋值添加到out
    猜你喜欢
    • 1970-01-01
    • 2019-03-23
    • 2021-07-05
    • 1970-01-01
    • 2016-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多