【问题标题】:Creating list from data table, then using it in loop从数据表创建列表,然后在循环中使用它
【发布时间】:2020-05-13 08:23:48
【问题描述】:

这似乎应该是微不足道的,但我无法让它工作,这让我发疯。我有一个包含几列的数据表,包括 sGEOID,即地理 ID。我想提取 sGEOID 的唯一值列表,然后使用每个值运行一个循环。代码没有多次运行循环,每次循环变量取一个 sGEOID 值,而是运行一次循环,循环变量取一个多元素列表的值。我发现让循环正常工作的唯一方法是显式创建列表,而不是从数据表中的值中提取它,这对于工作版本来说不是一个可行的选择。

这是代码,以及每次尝试的结果:

# Create simplified version of data table
dtObs = data.table(
  sGEOID = c("A","B","B",'C'),
  iVal = 1:4
)

print(dtObs)
# result
#   sGEOID iVal
#1: A 1
#2: B 2
#3: B 3
#4: C 4

# Create new data table with unique values of sGEOID
dtStates <- dtObs[, list(iCnt= .N), by = c('sGEOID')][order(sGEOID)]
print(dtStates)
# result
#   sGEOID iCnt
#1: A 1
#2: B 2
#3: C 1

# Loop through values in column of data table dtStates: FAILS
for (lasGEOID in dtStates[,1]) {
  print(lasGEOID)
  print('new line')
}
# result
# "A" "B" "C"
# "new line"

# Extract unique values into list
llsGEOIDs <- dtStates[,c('sGEOID')]
typeof(llsGEOIDs)
# result
#[1] "list"
print(llsGEOIDs)
# result
#   sGEOID
#1: A
#2: B
#3: C

# Loop through elements of list: FAILS
for (lasGEOID in llsGEOIDs) {
  print(lasGEOID)
  print('new line')
}
# result
#[1] "A" "B" "C"
#[1] "new line"

# Create list directly as list
# This is not a viable option for the real code
llsGEOIDs <- list('A','B','C')
print(llsGEOIDs)
# result
#[[1]]
#[1] "A"
#
#[[2]]
#[1] "B"
#
#[[3]]
#[1] "C"
#

# Loop through elements of list: WORKS
for (lasGEOID in llsGEOIDs) {
  #lasGEOID <- '06'
  print(lasGEOID)
  print('new line')
}
# result
#[1] "A"
#[1] "new line"
#[1] "B"
#[1] "new line"
#[1] "C"
#[1] "new line"

【问题讨论】:

    标签: r list loops


    【解决方案1】:

    dtStates[,1] 仍然是带有 1 列的 data.table,在 for 循环中被视为 1 个对象,因此所有值都打印在一起,您需要将这些值转换为向量。

    一种简单的方法是使用[[

    for (lasGEOID in dtStates[[1]]) {
       print(lasGEOID)
       print('new line')
    }
    
    #[1] "A"
    #[1] "new line"
    #[1] "B"
    #[1] "new line"
    #[1] "C"
    #[1] "new line"
    

    附注:.N 给出每个sGEOID 中的行数,如果您想计算唯一值,您可能需要使用uniqueN

    【讨论】:

    • 谢谢。那成功了。这就是我认为我对使用 llsGEOIDs 的版本所做的事情,它是一个列表。知道为什么这不起作用吗?我尝试了另一个版本,为了简单起见,我在示例中省略了该版本,它使用 llsGEOIDs &lt;- as.list(dtStates[,c('sGEOID')]) 创建了 llsGEOID,它产生了相同的(错误的)输出。
    • @rks13 不,那仍然是 1 列数据框。检查什么会起作用的一个简单技巧是使用lengthlength(dtStates[,c('sGEOID')]) 是 1,length(as.list(dtStates[,c('sGEOID')])) 也是,但 length(dtStates[[1]]) 是 3。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 2014-03-31
    • 2019-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多