簡體   English   中英

如果運行兩次,apply函數將返回列表列表

[英]apply function returns list of lists if run twice

我有這樣的df

a1 <- c(1,2,NA)
a2 <- c(3,4,NA)
a3 <- c(4,5,6)
a1_fill <- c(1,2,3)
a2_fill <- c(3,4,5)
a3_fill <- c(4,5,6)
b1 <- c(4,3,1)
b2 <- c(2,NA,9)
b3 <- c(NA,3,5)
b1_fill <- c(4,3,1)
b2_fill <- c(2,1,9)
b3_fill <- c(8,3,5)
df <- data.frame(a1,a2,a3,b1,b2,b3,a1_fill,a2_fill,a3_fill,b1_fill,b2_fill,b3_fill)

我想創建兩個新列,它們的值來自fill cols,它們不出現在相應的ab col中。 我是這樣的

df$missingA <- apply(df,1,function(x) setdiff(x[which(grepl("a",names(x),fixed = TRUE) & grepl("fill",names(x),fixed = TRUE))],x[which(grepl("a",names(x),fixed = TRUE) & !grepl("fill",names(x),fixed = TRUE))]))
df$missingB <- apply(df,1,function(x) setdiff(x[which(grepl("b",names(x),fixed = TRUE) & grepl("fill",names(x),fixed = TRUE))],x[which(grepl("b",names(x),fixed = TRUE) & !grepl("fill",names(x),fixed = TRUE))]))

由於某種原因,當我運行上面的代碼時,第二行運行返回一行列表,而第一行返回數字列表。 為什么是這樣?

這取決於行的運行順序。 我們可以使用下面的代碼來確定列中元素的類

class(df$missingA[[1]]) # Class of first element is numeric
class(df$missingB[[1]]) # Class of first element is list

從干凈的數據集開始,如果您首先創建missingB,然后創建missingA,則會看到missingA將是列表列表,而missingB將是數字列表(類型相反)。

df$missingB <- apply(df,1,function(x) 
  setdiff(
    x[which(
      grepl("b",names(x),fixed = TRUE) & 
      grepl("fill",names(x),fixed = TRUE))
    ],
    x[which(
      grepl("b",names(x),fixed = TRUE) & 
      !grepl("fill",names(x),fixed = TRUE))
    ]
  )
)


df$missingA <- apply(df,1,function(x) 
  setdiff(
    x[which(
      grepl("a",names(x),fixed = TRUE) & 
      grepl("fill",names(x),fixed = TRUE))
    ],
    x[which(
      grepl("a",names(x),fixed = TRUE) & 
      !grepl("fill",names(x),fixed = TRUE))
    ]
  )
)

class(df$missingA[[1]]) # Class of first element is list
class(df$missingB[[1]]) # Class of first element is numeric

我的猜測是正在發生以下情況。 您將從一個僅包含數字列的數據框開始。 R嘗試通過將列表的類型與數字匹配來提供幫助。 當添加第二列時,數據框不再僅由數字列組成,因為現在列出了一種類型,因此R不會嘗試更新類型。

要對此進行測試,您可以在添加missingA和missingB之前添加一個無數值的列,例如:

df$text <- list("a","b","C")

現在missingA和missingB都將被創建為列表列表

保留類型由apply語句生成的類型的另一種方法是將輸出分配給中間變量

missingA <- apply(df,1,function(x) 
setdiff(
  x[which(
    grepl("a",names(x),fixed = TRUE) & 
    grepl("fill",names(x),fixed = TRUE))
  ],
  x[which(
    grepl("a",names(x),fixed = TRUE) & 
    !grepl("fill",names(x),fixed = TRUE))
  ]
 )
)

df$missingA <- missingA

總而言之,您看到的差異不是由apply語句或它們產生的輸出引起的,而是由將數據添加到數據幀的方式引起的。 希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM