2017-08-07 78 views
0

我想根據該模式中的R變換的數據幀:收集多個列入逗號,分隔列表

enter image description here

注意,先前熱編碼屬性Att_1收集爲一個逗號在單個單元格中爲IDy分隔列表。如何在R中執行此操作(例如,使用tidyr函數)?

test <- data.frame(ID = c("IDx", "IDy"), Att_1_1 = c(0,0), Att_1_2 = c(1,1), Att_1_3 = c(0, 1), Att_2 = c(1,1), Att_3 = c(1,0)) 

回答

3

在基礎R,你可以做到以下幾點。

# set up new dataframe 
res <- test[-(2:4)] 

# add new varible 
res$Att_1 <- apply(test[, 2:4], 1, function(x) c(names(test)[2:4][as.logical(x)])) 

這裏,apply循環通過所述子集data.frame的行和返回的名稱,其中行單元的值等於1時,使用邏輯子集的載體。

這將返回

res 
    ID Att_2 Att_3   Att_1 
1 IDx  1  1   Att_1_2 
2 IDy  1  0 Att_1_2, Att_1_3 

注意

res[["Att_1"]] <- ... 

也會起作用。

+0

還有一個問題。我試圖通過編寫res [,「Att_1」]而不是res $ Att_1來更改代碼,但它不起作用。 apply命令返回一個列表。它背後的魔法是什麼? ;) – CodingButStillAlive

+0

您可以通過檢查'[<。。data.frame'和'$ < - 。data.frame'的代碼或多或少地得到一個想法。第一個很長,包含了一些檢查,因爲'[<-'必須處理比'$ < - '更多的情況。大約3/4通過後,您會看到警告消息的打印輸出,後面是'new.cols < - new.cols [seq_len(p)]'行。我相信這會從'apply'截斷列表輸出以包含第一個元素。 '$ < - '的代碼要短得多,並最終使用我在上面的答案中添加的'x [[name]] < - value'。 – lmo

+1

感謝您的全面解釋。順便說一句。我用明確的粘貼代替了這一行,並將其摺疊以將元素連接到逗號分隔的字符串中,因爲它們在打印輸出中以其他方式顯示。感謝這真棒的幫助。最好的祝福! – CodingButStillAlive

3

作爲OP請求tidyr的功能,我們gather數據集成「長」格式,filter其中「VAL」爲1的行中,由「編號」,paste「key」的列進行分組來創建summarise d柱「Att_1」和left_join通過「標識」與原始數據集

library(tidyverse) 
test %>% 
    gather(key, val, Att_1_1:Att_1_3) %>% 
    filter(val==1) %>% 
    group_by(ID) %>% 
    summarise(Att_1 = toString(key)) %>% 
    left_join(df1[-(2:4)], ., by = "ID") %>% 
    select(ID, Att_1, Att_2, Att_3) 
# ID   Att_1 Att_2 Att_3 
#1 IDx   Att_1_2  1  1 
#2 IDy Att_1_2, Att_1_3  1  0 
+1

@Sotos謝謝,我是基於OP顯示的圖像編碼。沒有看到OP改變了 – akrun

+0

哇。驚人!非常感謝!但說實話,我真的希望有一個更簡單的解決方案。我的意思是......提出的解決方案真的是一門藝術。而我的真實數據框真的非常龐大而複雜。 PS:我編輯帖子以使測試數據幀與圖片一致,即ID而不是ID。 – CodingButStillAlive

+0

也許有非tidyr函數更直接的解決方案!? – CodingButStillAlive