我有以下的數據幀(數據),從該我會想提取和打印列標題過的位置有一個非零元素:提取列標題
M1 M2 M3 M4
2 0 1 0 1
5 1 -1 0 0
7 0 1 1 0
需要的輸出:
2: M2 M4
5: M1 M2
7: M2 M3
到目前爲止,我的R代碼裏面是不工作:
colnames(data)[which(data[2] !=0),]
幫助將不勝感激。由於
我有以下的數據幀(數據),從該我會想提取和打印列標題過的位置有一個非零元素:提取列標題
M1 M2 M3 M4
2 0 1 0 1
5 1 -1 0 0
7 0 1 1 0
需要的輸出:
2: M2 M4
5: M1 M2
7: M2 M3
到目前爲止,我的R代碼裏面是不工作:
colnames(data)[which(data[2] !=0),]
幫助將不勝感激。由於
讓我們的不規則的結果更一般的情況:
dat <- structure(list(M1 = c(0L, 1L, 0L), M2 = c(1L, -1L, 1L), M3 = -1:1,
M4 = c(1L, 0L, 0L)), .Names = c("M1", "M2", "M3", "M4"),
class = "data.frame", row.names = c("2", "5", "7"))
> dat
M1 M2 M3 M4
2 0 1 -1 1
5 1 -1 0 0
7 0 1 1 0
內申請「循環」構成一個邏輯組向量。因爲R是以列爲導向的,所以第二級處理是在列上完成的。外應用「循環」從colnames提取適當項目:
apply(apply(dat,1, as.logical) , 2, function(ll) colnames(dat)[ll])
$`2`
[1] "M2" "M3" "M4"
$`5`
[1] "M1" "M2"
$`7`
[1] "M2" "M3"
也可能已經提取出的陣列指示器版本(),然後處理結果:
> which(dat != 0, arr.ind=TRUE)
row col
5 2 1
2 1 2
5 2 2
7 3 2
2 1 3
7 3 3
2 1 4
我在添加1第一行治療不規則的情況下
mm <- read.table(text='M1 M2 M3 M4
2 0 1 1 1
5 1 -1 0 0
7 0 1 1 0',header=TRUE)
res <- apply(mm != 0,1,function(x)colnames(mm)[x])
$`2`
[1] "M2" "M3" "M4"
$`5`
[1] "M1" "M2"
$`7`
[1] "M2" "M3"
編輯是一致的,並返回一個列表:
res <- apply(mm != 0,1,function(x)colnames(mm)[x])
if (!is.null(dim(res)) split(res,seq_along(res[,1]))
這將始終返回一個列表:
Map(`[`, list(names(df)), split(col(df)[df != 0],
row(df)[df != 0]))
# [[1]]
# [1] "M2" "M4"
#
# [[2]]
# [1] "M1" "M2"
#
# [[3]]
# [1] "M2" "M3"
(你可以在裏面setNames(..., rownames(df))
包裝中,如果你想要列表分享df
的行名。)
當然+ 1 ....!elegant! – agstudy
我很感謝你的幫助flodel。請解釋map()是如何在這個上下文中使用的,謝謝 – user27976
如果你熟悉函數,Map'就像'mapply'一樣,除了它總是返回一個名單。這裏的語法是'Map(f,a,b)',其中'a'和'b'是列表(你可以把它們想象成矢量)。 'Map'將遍歷這兩個列表並運行'f(a [[i]],b [[i]])''。請注意,'a'的長度爲1,所以它會被回收,所以它實際上對所有'i'運行'f(a [[1]],b [[i]])。現在,如果你用上面的這些代替'f','a','b',那應該是有道理的。 – flodel
因爲你不能保證所有行將具有相同數量的列名稱,您應該準備好將列表作爲輸出。 –
'colnames(data)'是一個向量,所以我猜你應該在[]內部沒有逗號。使用'colnames(data)[which(data [2,]!= 0)] – Frank